Skip to content

Commit 3837f67

Browse files
committed
Initial step of using PrettyPair in Bool.
1 parent 57b23da commit 3837f67

File tree

10 files changed

+63
-38
lines changed

10 files changed

+63
-38
lines changed

scalactic/src/main/scala/org/scalactic/Bool.scala

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ trait Bool {
3434
private def makeString(raw: String, args: Array[Any]): String =
3535
Resources.formatString(raw, args.map(prettifier.apply))
3636

37+
lazy val analysis: scala.collection.immutable.IndexedSeq[String] = Vector.empty
38+
3739
/**
3840
* Construct and return failure message, by applying arguments returned from <code>failureMessageArgs</code> to
3941
* raw message returned from <code>rawFailureMessage</code>
@@ -657,6 +659,23 @@ private[scalactic] class BinaryMacroBool(left: Any, operator: String, right: Any
657659
def this(left: Any, operator: String, right: Any, bool: Bool, prettifier: Prettifier) =
658660
this(left, operator, right, bool.value, prettifier)
659661

662+
private lazy val prettyPair: PrettyPair = {
663+
val leftValue =
664+
left match {
665+
case aEqualizer: org.scalactic.TripleEqualsSupport#Equalizer[_] => aEqualizer.leftSide
666+
case aEqualizer: org.scalactic.TripleEqualsSupport#CheckingEqualizer[_] => aEqualizer.leftSide
667+
case _ => left
668+
}
669+
prettifier.apply(leftValue, right)
670+
}
671+
672+
override lazy val analysis: scala.collection.immutable.IndexedSeq[String] = {
673+
operator match {
674+
case "==" | "===" => prettyPair.analysis.map(Vector(_)).getOrElse(Vector.empty)
675+
case _ => Vector.empty
676+
}
677+
}
678+
660679
/**
661680
* the <code>Boolean</code> value of this <code>Bool</code>.
662681
*/

scalactic/src/main/scala/org/scalactic/PrettyPair.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ package org.scalactic
1818
case class PrettyPair(
1919
left: String,
2020
right: String,
21-
hint: Option[String]
21+
analysis: Option[String]
2222
)
2323

2424

scalatest-test/src/test/scala/org/scalatest/exceptions/StackDepthExceptionSpec.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class StackDepthExceptionSpec extends FunSpec with Matchers with TableDrivenProp
7373
def positionExamples =
7474
Table(
7575
"exception",
76-
new TestFailedException((_: StackDepthException) => Some("message"), None, Left(source.Position.here), None),
76+
new TestFailedException((_: StackDepthException) => Some("message"), None, Left(source.Position.here), None, Vector.empty),
7777
// SKIP-SCALATESTJS-START
7878
new JUnitTestFailedError(Some("message"), None, Left(source.Position.here), None),
7979
// SKIP-SCALATESTJS-END
@@ -89,7 +89,7 @@ class StackDepthExceptionSpec extends FunSpec with Matchers with TableDrivenProp
8989
def stackDepthExamples =
9090
Table(
9191
"exception",
92-
new TestFailedException((_: StackDepthException) => Some("message"), None, Right((_: StackDepthException) => 3), None),
92+
new TestFailedException((_: StackDepthException) => Some("message"), None, Right((_: StackDepthException) => 3), None, Vector.empty),
9393
// SKIP-SCALATESTJS-START
9494
new JUnitTestFailedError(Some("message"), None, Right(3), None),
9595
// SKIP-SCALATESTJS-END

scalatest-test/src/test/scala/org/scalatest/tools/StringReporterSuite.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,14 +382,14 @@ class StringReporterSuite extends FunSuite with Matchers {
382382
test("withPossibleLineNumber returns simple file name on same line if presentFilePathname is false") {
383383
import org.scalactic.source
384384
import StringReporter.withPossibleLineNumber
385-
val result = withPossibleLineNumber("oops", Some(new TestFailedException((_: StackDepthException) => Some("also oops"), None, Left(source.Position.here), None)), false)
385+
val result = withPossibleLineNumber("oops", Some(new TestFailedException((_: StackDepthException) => Some("also oops"), None, Left(source.Position.here), None, Vector.empty)), false)
386386
assert(result === "oops (StringReporterSuite.scala:" + (thisLineNumber - 1) + ")")
387387
}
388388

389389
test("withPossibleLineNumber returns full file pathname on next line if presentFilePathname is true and it is available") {
390390
import StringReporter.withPossibleLineNumber
391391
import org.scalactic.source
392-
val result = withPossibleLineNumber("oops", Some(new TestFailedException((_: StackDepthException) => Some("also oops"), None, Left(source.Position.here), None)), true)
392+
val result = withPossibleLineNumber("oops", Some(new TestFailedException((_: StackDepthException) => Some("also oops"), None, Left(source.Position.here), None, Vector.empty)), true)
393393
assert(result startsWith "oops\n** ")
394394
if (System.getenv("SCALACTIC_FILL_FILE_PATHNAMES") != null && System.getenv("SCALACTIC_FILL_FILE_PATHNAMES") == "yes")
395395
assert(result endsWith "org/scalatest/tools/StringReporterSuite.scala:" + (thisLineNumber - 3) + " **")

scalatest/src/main/scala/org/scalatest/Assertions.scala

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,8 @@ trait Assertions extends TripleEquals {
467467
*/
468468
def assert(condition: Boolean)(implicit prettifier: Prettifier, pos: source.Position): Assertion = macro AssertionsMacro.assert
469469

470-
private[scalatest] def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position): Throwable =
471-
new exceptions.TestFailedException(toExceptionFunction(optionalMessage), optionalCause, pos)
470+
private[scalatest] def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position, analysis: scala.collection.immutable.IndexedSeq[String]): Throwable =
471+
new exceptions.TestFailedException(toExceptionFunction(optionalMessage), optionalCause, Left(pos), None, analysis)
472472

473473
private[scalatest] def newTestCanceledException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position): Throwable =
474474
new exceptions.TestCanceledException(toExceptionFunction(optionalMessage), optionalCause, pos, None)
@@ -752,7 +752,7 @@ trait Assertions extends TripleEquals {
752752
case u: Throwable => {
753753
if (!clazz.isAssignableFrom(u.getClass)) {
754754
val s = Resources.wrongException(clazz.getName, u.getClass.getName)
755-
throw newAssertionFailedException(Some(s), Some(u), pos)
755+
throw newAssertionFailedException(Some(s), Some(u), pos, Vector.empty)
756756
}
757757
else {
758758
Some(u)
@@ -762,7 +762,7 @@ trait Assertions extends TripleEquals {
762762
caught match {
763763
case None =>
764764
val message = Resources.exceptionExpected(clazz.getName)
765-
throw newAssertionFailedException(Some(message), None, pos)
765+
throw newAssertionFailedException(Some(message), None, pos, Vector.empty)
766766
case Some(e) => e.asInstanceOf[T] // I know this cast will succeed, becuase isAssignableFrom succeeded above
767767
}
768768
}
@@ -811,7 +811,7 @@ trait Assertions extends TripleEquals {
811811
case u: Throwable => {
812812
if (!clazz.isAssignableFrom(u.getClass)) {
813813
val s = Resources.wrongException(clazz.getName, u.getClass.getName)
814-
throw newAssertionFailedException(Some(s), Some(u), pos)
814+
throw newAssertionFailedException(Some(s), Some(u), pos, Vector.empty)
815815
}
816816
else true
817817
}
@@ -821,7 +821,7 @@ trait Assertions extends TripleEquals {
821821
}
822822
else {
823823
val message = Resources.exceptionExpected(clazz.getName)
824-
throw newAssertionFailedException(Some(message), None, pos)
824+
throw newAssertionFailedException(Some(message), None, pos, Vector.empty)
825825
}
826826
}
827827

@@ -943,7 +943,7 @@ trait Assertions extends TripleEquals {
943943
val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected)
944944
val s = FailureMessages.expectedButGot(prettifier, exp, act)
945945
val fullMsg = AppendedClues.appendClue(s, clue.toString)
946-
throw newAssertionFailedException(Some(fullMsg), None, pos)
946+
throw newAssertionFailedException(Some(fullMsg), None, pos, Vector.empty)
947947
}
948948
Succeeded
949949
}
@@ -963,7 +963,7 @@ trait Assertions extends TripleEquals {
963963
if (!areEqualComparingArraysStructurally(actual, expected)) {
964964
val (act, exp) = Suite.getObjectsForFailureMessage(actual, expected)
965965
val s = FailureMessages.expectedButGot(prettifier, exp, act)
966-
throw newAssertionFailedException(Some(s), None, pos)
966+
throw newAssertionFailedException(Some(s), None, pos, Vector.empty)
967967
}
968968
Succeeded
969969
}
@@ -1015,7 +1015,7 @@ trait Assertions extends TripleEquals {
10151015
/**
10161016
* Throws <code>TestFailedException</code> to indicate a test failed.
10171017
*/
1018-
def fail()(implicit pos: source.Position): Nothing = { throw newAssertionFailedException(None, None, pos) }
1018+
def fail()(implicit pos: source.Position): Nothing = { throw newAssertionFailedException(None, None, pos, Vector.empty) }
10191019

10201020
/**
10211021
* Throws <code>TestFailedException</code>, with the passed
@@ -1029,7 +1029,7 @@ trait Assertions extends TripleEquals {
10291029

10301030
requireNonNull(message)
10311031

1032-
throw newAssertionFailedException(Some(message), None, pos)
1032+
throw newAssertionFailedException(Some(message), None, pos, Vector.empty)
10331033
}
10341034

10351035
/**
@@ -1045,7 +1045,7 @@ trait Assertions extends TripleEquals {
10451045

10461046
requireNonNull(message, cause)
10471047

1048-
throw newAssertionFailedException(Some(message), Some(cause), pos)
1048+
throw newAssertionFailedException(Some(message), Some(cause), pos, Vector.empty)
10491049
}
10501050

10511051
/**
@@ -1061,7 +1061,7 @@ trait Assertions extends TripleEquals {
10611061

10621062
requireNonNull(cause)
10631063

1064-
throw newAssertionFailedException(None, Some(cause), pos)
1064+
throw newAssertionFailedException(None, Some(cause), pos, Vector.empty)
10651065
}
10661066

10671067
/**
@@ -1396,7 +1396,7 @@ object Assertions extends Assertions {
13961396
requireNonNull(clue)(prettifier, pos)
13971397
if (!bool.value) {
13981398
val failureMessage = if (Bool.isSimpleWithoutExpressionText(bool)) None else Some(bool.failureMessage)
1399-
throw newAssertionFailedException(append(failureMessage, clue), None, pos)
1399+
throw newAssertionFailedException(append(failureMessage, clue), None, pos, bool.analysis)
14001400
}
14011401
Succeeded
14021402
}

scalatest/src/main/scala/org/scalatest/DiagrammedAssertions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ object DiagrammedAssertions extends DiagrammedAssertions {
356356
if (!bool.value) {
357357
val failureMessage =
358358
Some(clue + Prettifier.lineSeparator + Prettifier.lineSeparator + renderDiagram(sourceText, bool.anchorValues))
359-
throw newAssertionFailedException(failureMessage, None, pos)
359+
throw newAssertionFailedException(failureMessage, None, pos, Vector.empty)
360360
}
361361
Succeeded
362362
}

scalatest/src/main/scala/org/scalatest/exceptions/PropertyCheckFailedException.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ abstract class PropertyCheckFailedException(
4444
val undecoratedMessage: String,
4545
val args: List[Any],
4646
optionalArgNames: Option[List[String]]
47-
) extends TestFailedException((sde: StackDepthException) => Some(messageFun(sde)), cause, posOrStackDepthFun, payload) {
47+
) extends TestFailedException((sde: StackDepthException) => Some(messageFun(sde)), cause, posOrStackDepthFun, payload, Vector.empty) {
4848

4949
/**
5050
* Constructs a <code>PropertyCheckFailedException</code> with given error message function, optional cause, stack depth function,

scalatest/src/main/scala/org/scalatest/exceptions/TestFailedDueToTimeoutException.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class TestFailedDueToTimeoutException(
4444
posOrStackDepthFun: Either[source.Position, StackDepthException => Int],
4545
payload: Option[Any],
4646
val timeout: Span
47-
) extends TestFailedException(messageFun, cause, posOrStackDepthFun, payload) with TimeoutField {
47+
) extends TestFailedException(messageFun, cause, posOrStackDepthFun, payload, Vector.empty) with TimeoutField {
4848

4949
/**
5050
* Constructs a <code>TestFailedDueToTimeoutException</code> with the given error message function, optional cause, source position and optional payload.

scalatest/src/main/scala/org/scalatest/exceptions/TestFailedException.scala

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class TestFailedException(
5050
messageFun: StackDepthException => Option[String],
5151
cause: Option[Throwable],
5252
posOrStackDepthFun: Either[source.Position, StackDepthException => Int],
53-
val payload: Option[Any]
53+
val payload: Option[Any],
54+
val analysis: scala.collection.immutable.IndexedSeq[String]
5455
) extends StackDepthException(messageFun, cause, posOrStackDepthFun) with ModifiableMessage[TestFailedException] with PayloadField with ModifiablePayload[TestFailedException] {
5556

5657
/**
@@ -66,7 +67,7 @@ class TestFailedException(
6667
cause: Option[Throwable],
6768
pos: source.Position,
6869
payload: Option[Any]
69-
) = this(messageFun, cause, Left(pos), payload)
70+
) = this(messageFun, cause, Left(pos), payload, Vector.empty)
7071

7172
/**
7273
* Constructs a <code>TestFailedException</code> with the given error message function, optional cause and source position.
@@ -79,7 +80,7 @@ class TestFailedException(
7980
messageFun: StackDepthException => Option[String],
8081
cause: Option[Throwable],
8182
pos: source.Position
82-
) = this(messageFun, cause, Left(pos), None)
83+
) = this(messageFun, cause, Left(pos), None, Vector.empty)
8384

8485
/**
8586
* Constructs a <code>TestFailedException</code> with pre-determined <code>message</code> and <code>failedCodeStackDepth</code>. (This was
@@ -92,7 +93,7 @@ class TestFailedException(
9293
* @throws NullArgumentException if either <code>message</code> of <code>cause</code> is <code>null</code>, or <code>Some(null)</code>.
9394
*/
9495
def this(messageFun: StackDepthException => Option[String], cause: Option[Throwable], failedCodeStackDepthFun: StackDepthException => Int) =
95-
this(messageFun, cause, Right(failedCodeStackDepthFun), None)
96+
this(messageFun, cause, Right(failedCodeStackDepthFun), None, Vector.empty)
9697

9798
/**
9899
* Constructs a <code>TestFailedException</code> with pre-determined <code>message</code> and <code>failedCodeStackDepth</code>. (This was
@@ -109,7 +110,8 @@ class TestFailedException(
109110
StackDepthException.toExceptionFunction(message),
110111
cause,
111112
Right((_: StackDepthException) => failedCodeStackDepth),
112-
None
113+
None,
114+
Vector.empty
113115
)
114116

115117
/**
@@ -123,7 +125,8 @@ class TestFailedException(
123125
StackDepthException.toExceptionFunction(None),
124126
None,
125127
Right((_: StackDepthException) => failedCodeStackDepth),
126-
None
128+
None,
129+
Vector.empty
127130
)
128131

129132
/**
@@ -142,7 +145,8 @@ class TestFailedException(
142145
},
143146
None,
144147
Right((_: StackDepthException) => failedCodeStackDepth),
145-
None
148+
None,
149+
Vector.empty
146150
)
147151

148152
/**
@@ -163,7 +167,8 @@ class TestFailedException(
163167
},
164168
Some(cause),
165169
Right((_: StackDepthException) => failedCodeStackDepth),
166-
None
170+
None,
171+
Vector.empty
167172
)
168173

169174
/**
@@ -191,7 +196,8 @@ class TestFailedException(
191196
Some(cause)
192197
},
193198
Right((_: StackDepthException) => failedCodeStackDepth),
194-
None
199+
None,
200+
Vector.empty
195201
)
196202

197203
/**
@@ -206,7 +212,7 @@ class TestFailedException(
206212
messageFun: StackDepthException => Option[String],
207213
cause: Option[Throwable],
208214
failedCodeStackDepthFun: StackDepthException => Int,
209-
payload: Option[Any]) = this(messageFun, cause, Right(failedCodeStackDepthFun), payload)
215+
payload: Option[Any]) = this(messageFun, cause, Right(failedCodeStackDepthFun), payload, Vector.empty)
210216

211217
/**
212218
* Returns an exception of class <code>TestFailedException</code> with <code>failedExceptionStackDepth</code> set to 0 and
@@ -216,7 +222,7 @@ class TestFailedException(
216222
*/
217223
def severedAtStackDepth: TestFailedException = {
218224
val truncated = getStackTrace.drop(failedCodeStackDepth)
219-
val e = new TestFailedException(messageFun, cause, posOrStackDepthFun, payload)
225+
val e = new TestFailedException(messageFun, cause, posOrStackDepthFun, payload, analysis)
220226
e.setStackTrace(truncated)
221227
e
222228
}
@@ -230,7 +236,7 @@ class TestFailedException(
230236
* the modified optional detail message for the result instance of <code>TestFailedException</code>.
231237
*/
232238
def modifyMessage(fun: Option[String] => Option[String]): TestFailedException = {
233-
val mod = new TestFailedException(StackDepthException.toExceptionFunction(fun(message)), cause, posOrStackDepthFun, payload) // TODO: Seems like here I could just compose the message functions and not evaluate them, in case it is never used
239+
val mod = new TestFailedException(StackDepthException.toExceptionFunction(fun(message)), cause, posOrStackDepthFun, payload, analysis) // TODO: Seems like here I could just compose the message functions and not evaluate them, in case it is never used
234240
mod.setStackTrace(getStackTrace)
235241
mod
236242
}
@@ -245,7 +251,7 @@ class TestFailedException(
245251
*/
246252
def modifyPayload(fun: Option[Any] => Option[Any]): TestFailedException = {
247253
val currentPayload = payload
248-
val mod = new TestFailedException(messageFun, cause, posOrStackDepthFun, fun(currentPayload)) // TODO: Should I be lazy about replacing the payload?
254+
val mod = new TestFailedException(messageFun, cause, posOrStackDepthFun, fun(currentPayload), analysis) // TODO: Should I be lazy about replacing the payload?
249255
mod.setStackTrace(getStackTrace)
250256
mod
251257
}
@@ -263,7 +269,7 @@ class TestFailedException(
263269
*/
264270
override def equals(other: Any): Boolean =
265271
other match {
266-
case that: TestFailedException => super.equals(that) && payload == that.payload
272+
case that: TestFailedException => super.equals(that) && payload == that.payload && analysis == that.analysis
267273
case _ => false
268274
}
269275

@@ -273,6 +279,6 @@ class TestFailedException(
273279
override def hashCode: Int =
274280
41 * (
275281
super.hashCode
276-
) + payload.hashCode
282+
) + payload.hashCode + analysis.hashCode
277283
}
278284

scalatest/src/main/scala/org/scalatest/junit/AssertionsForJUnit.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ import org.scalactic._
9696
*/
9797
trait AssertionsForJUnit extends Assertions {
9898

99-
private[scalatest] override def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position): Throwable = {
99+
private[scalatest] override def newAssertionFailedException(optionalMessage: Option[String], optionalCause: Option[Throwable], pos: source.Position, differences: scala.collection.immutable.IndexedSeq[String]): Throwable = {
100100
new JUnitTestFailedError(optionalMessage, optionalCause, pos, None)
101101
}
102102

@@ -201,7 +201,7 @@ object AssertionsForJUnit extends AssertionsForJUnit {
201201
requireNonNull(clue)(prettifier, pos)
202202
if (!bool.value) {
203203
val failureMessage = if (Bool.isSimpleWithoutExpressionText(bool)) None else Some(bool.failureMessage)
204-
throw newAssertionFailedException(append(failureMessage, clue), None, pos)
204+
throw newAssertionFailedException(append(failureMessage, clue), None, pos, bool.analysis)
205205
}
206206
Succeeded
207207
}

0 commit comments

Comments
 (0)