traitTripleEqualsSupport extends AnyRef

Trait that defines abstract methods used to enforce compile-time type constraints for equality comparisons, and defines === and !== operators
used by matchers.

The abstract methods of this trait are selectively implemented as implicit by subclasses to enable a spectrum of type constraints for the
=== and !== operators. As an illustration, if in the expression, a === b, the type of a
is A and b is B, the following three levels of compile-time checking can be obtained from
TripleEqualsSupport subtraits:

Conversion checked - A must be a subtype of B, or vice versa, or an implicit conversion must be available that converts
A to B, or vice versa. (Both A and B can be the same type, because a type is considered a subtype
of itself.)
This (intermediate) constraint level is available from subtraits ConversionCheckedTripleEquals and ConversionCheckedLegacyTripleEquals.

Type checked - A must be a subtype of B, or vice versa.
(Both A and B can be the same type, because a type is considered a subtype
of itself.)
This (strongest) constraint level is available from subtraits TypeCheckedTripleEquals and TypeCheckedLegacyTripleEquals.

The difference between the regular and “legacy” variants of each pair of traits is that the === and !== operators
provided by the regular variants result in Boolean, whereas those of the legacy variants result in Option[String]. For example, were you
to mix in TripleEquals, the expression 1 + 1 === 3 would return false. Were you to mix in LegacyTripleEquals,
by contrast, the expression 1 + 1 === 3 would return Some("2 did not equal 3").

The purpose of the legacy variants is to maintain compatibility with
existing code that uses ScalaTest's original === defined in trait org.scalatest.Assertions. This
=== operator returned an
Option[String] to facilitate better error messages. With the advent of macros in Scala 2.10, it is possible to obtain good error messages by making
assert a macro. Once ScalaTest no longer supports Scala 2.9, the legacy variants (LegacyTripleEquals,
ConversionCheckedLegacyTripleEquals, and TypeCheckedLegacyTripleEquals) will be deprecated and eventually removed, === will
return only Boolean, and good error
messages will be obtained via macros.

This trait defines all methods that need to be defined implicitly by the six subtraits so that if multiple subtraits are used together, the inner-most
subtrait in scope can not only enable the implicits it needs by overriding or hiding those methods (currently-in-scope as regular, non-implicit methods) and making
them implicit, it can also disable any implicits enabled by its sibling subtraits in enclosing scopes. For example, if your test class mixes
in TypeCheckedTripleEquals, inside your test class the following methods will be implicit:

convertToCheckingEqualizer

typeCheckedConstraint

lowPriorityTypeCheckedConstraint

convertEquivalenceToAToBConstraint

convertEquivalenceToBToAConstraint

If in the body of a test you want to turn off the type checking, you can import the members
of TripleEquals in the body of that test. This will not only hide
non-implicit methods convertToEqualizerunconstrainedEquality of TypeCheckedTripleEquals,
replacing those with implicit ones defined in TripleEquals, it will also hide the three methods made implicit in TypeCheckedTripleEquals
(and listed above), replacing them by non-implicit ones.

In short, you should be able to select a primary constraint level via either a mixin or import, then change that in nested scopes
however you want, again either through a mixin or import, without getting any implicit conversion ambiguity. The innermost constraint level in scope
will always be in force.

Provides a Constraint[A, B] for any two types A and B, enforcing the type constraint
that B must be a subtype of A, given an explicitEquivalence[A].

Provides a Constraint[A, B] for any two types A and B, enforcing the type constraint
that B must be a subtype of A, given an explicitEquivalence[A].

This method is used to enable the Explicitly DSL for
TypeCheckedTripleEquals by requiring an explicit Equivalance[B], but
taking an implicit function that provides evidence that A is a subtype of B. For example, under TypeCheckedTripleEquals,
this method (as an implicit method), would be used to compile this statement:

Provides a Constraint[A, B] class for any two types A and B, enforcing the type constraint that B is
implicitly convertible to A, given an explicitEquivalence[A].

Provides a Constraint[A, B] class for any two types A and B, enforcing the type constraint that B is
implicitly convertible to A, given an explicitEquivalence[A].

This method is used to enable the Explicitly DSL for
ConversionCheckedTripleEquals by requiring an explicit Equivalance[A], but
taking an implicit function that converts from B to A. For example, under ConversionCheckedTripleEquals,
this method (as an implicit method), would be used to compile this statement: