Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty Print Tuples #2160

Merged
merged 10 commits into from Aug 22, 2022
Expand Up @@ -401,19 +401,38 @@ class PrettifierSpec extends funspec.AnyFunSpec with matchers.should.Matchers {
Prettifier.default(new Fred) shouldBe "It's Fred all the way down"
}
// SKIP-DOTTY-END
it("should truncate collection when used with Prettifier.truncateAt") {

case class Person(name: String, age: Int)

it("should pretty print case class") {
val p = Person("John Lee", 35)
Prettifier.default(p) should be ("Person(\"John Lee\", 35)")
}

it("should pretty print Tuple") {
Prettifier.default(("John Lee", 35)) should be ("(\"John Lee\", 35)")
}
}

describe("the truncating Prettifier") {
it("should truncate collection") {
val col = List(1, 2, 3)
val prettifier = Prettifier.truncateAt(SizeLimit(2))
prettifier(col) shouldBe "List(1, 2, ...)"
}

case class CaseClazz(data: List[Int])

it("should truncate collection inside of a case class when used with Prettifier.truncateAt") {
it("should truncate collection inside of a case class") {
val caseClass = CaseClazz(List(1, 2, 3))
val prettifier = Prettifier.truncateAt(SizeLimit(2))
prettifier(caseClass) shouldBe "CaseClazz(List(1, 2, ...))"
}

it("should pretty print Tuple") {
val prettifier = Prettifier.truncateAt(SizeLimit(2))
prettifier(("John Lee", 35)) should be ("(\"John Lee\", 35)")
}
}
}

7 changes: 6 additions & 1 deletion jvm/scalactic/src/main/scala/org/scalactic/Prettifier.scala
Expand Up @@ -182,6 +182,8 @@ private[scalactic] class DefaultPrettifier extends Prettifier {
// overridden so lets use our custom prettifying otherwise we just use .toString.
if (caseClazz.toString.startsWith(s"${caseClazz.productPrefix}("))
s"${caseClazz.productPrefix}(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz)).mkString(", ") + ")"
else if (caseClazz.productPrefix.startsWith("Tuple"))
"(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz)).mkString(", ") + ")"
else
caseClazz.toString
case anythingElse => anythingElse.toString
Expand Down Expand Up @@ -288,7 +290,10 @@ private[scalactic] class TruncatingPrettifier(sizeLimit: SizeLimit) extends Defa
// Unlike in DefaultPrettifier where we check if a custom `.toString` has been overridden, with
// TruncatingPrettifier the priority is truncating the enclosed data at all costs hence why we always
// truncate the inner fields.
s"${caseClazz.productPrefix}(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz)).mkString(", ") + ")"
if (caseClazz.productPrefix.startsWith("Tuple"))
s"(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz)).mkString(", ") + ")"
else
s"${caseClazz.productPrefix}(" + caseClazz.productIterator.map(prettify(_, processed + caseClazz)).mkString(", ") + ")"
case anythingElse => anythingElse.toString
}
}
Expand Down
Expand Up @@ -28,7 +28,7 @@ class AllElementsOfContainMatcherSpec extends funspec.AnyFunSpec {
def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = Prettifier.default(left)
val rightText = Prettifier.default(right)
e.message should be (Some(leftText + " did not contain all elements of " + right))
e.message should be (Some(leftText + " did not contain all elements of " + rightText))
e.failedCodeFileName should be (Some("AllElementsOfContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down
Expand Up @@ -30,7 +30,7 @@ class AllOfContainMatcherSpec extends funspec.AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " did not contain all of (" + right.mkString(", ") + ")"))
e.message should be (Some(leftText + " did not contain all of (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ")"))
e.failedCodeFileName should be (Some("AllOfContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down Expand Up @@ -194,7 +194,7 @@ class AllOfContainMatcherSpec extends funspec.AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " contained all of (" + right.mkString(", ") + ")"))
e.message should be (Some(leftText + " contained all of (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ")"))
e.failedCodeFileName should be (Some("AllOfContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down
Expand Up @@ -32,7 +32,7 @@ class InOrderContainMatcherSpec extends AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " did not contain all of (" + right.mkString(", ") + ") in order"))
e.message should be (Some(leftText + " did not contain all of (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ") in order"))
e.failedCodeFileName should be (Some("InOrderContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down Expand Up @@ -263,7 +263,7 @@ class InOrderContainMatcherSpec extends AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " contained all of (" + right.mkString(", ") + ") in order"))
e.message should be (Some(leftText + " contained all of (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ") in order"))
e.failedCodeFileName should be (Some("InOrderContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down
Expand Up @@ -33,7 +33,7 @@ class InOrderOnlyContainMatcherSpec extends AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " did not contain only (" + right.mkString(", ") + ") in order"))
e.message should be (Some(leftText + " did not contain only (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ") in order"))
e.failedCodeFileName should be (Some("InOrderOnlyContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down Expand Up @@ -162,7 +162,7 @@ class InOrderOnlyContainMatcherSpec extends AnyFunSpec {

def checkStackDepth(e: exceptions.StackDepthException, left: Any, right: GenTraversable[Any], lineNumber: Int): Unit = {
val leftText = FailureMessages.decorateToStringValue(prettifier, left)
e.message should be (Some(leftText + " contained only (" + right.mkString(", ") + ") in order"))
e.message should be (Some(leftText + " contained only (" + right.map(e => FailureMessages.decorateToStringValue(prettifier, e)).mkString(", ") + ") in order"))
e.failedCodeFileName should be (Some("InOrderOnlyContainMatcherSpec.scala"))
e.failedCodeLineNumber should be (Some(lineNumber))
}
Expand Down