Skip to content

Commit

Permalink
Make BeSameAs and NotBeSameAs handle nulls
Browse files Browse the repository at this point in the history
  • Loading branch information
cmeeren committed Jul 25, 2023
1 parent f52d017 commit b8300a8
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 38 deletions.
45 changes: 37 additions & 8 deletions src/Faqt.Tests/BasicAssertions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,13 @@ module BeSameAs =


[<Fact>]
let ``Throws ArgumentNullException for null argument`` () =
Assert.Throws<ArgumentNullException>(fun () -> "a".Should().BeSameAs(null) |> ignore)
let ``Passes if both subject and expected are null references`` () =
(null: string).Should().BeSameAs(null).Id<And<string>>().And.BeNull()


[<Fact>]
let ``Fails with expected message for null`` () =
let x = null
let ``Fails with expected message if only subject is null`` () =
let x: string = null
let y = "asd"

fun () -> x.Should().BeSameAs(y)
Expand All @@ -276,6 +276,23 @@ null
"""


[<Fact>]
let ``Fails with expected message if only expected is null`` () =
let x = "asd"
let y: string = null

fun () -> x.Should().BeSameAs(y)
|> assertExnMsg
$"""
x
should be reference equal to
null
but was
%i{LanguagePrimitives.PhysicalHash x} System.String
"asd"
"""


[<Fact>]
let ``Fails with expected message for non-reference-equal values of generic type even if they are equal`` () =
let x = Map.empty.Add("a", 1)
Expand Down Expand Up @@ -322,13 +339,25 @@ module NotBeSameAs =


[<Fact>]
let ``Passes for null`` () =
null.Should().NotBeSameAs("foo").Id<And<string>>()
let ``Passes if only subject is null reference`` () = null.Should().NotBeSameAs("asd")


[<Fact>]
let ``Throws ArgumentNullException for null argument`` () =
Assert.Throws<ArgumentNullException>(fun () -> "a".Should().NotBeSameAs(null) |> ignore)
let ``Passes if only expected is null reference`` () = "asd".Should().NotBeSameAs(null)


[<Fact>]
let ``Fails with expected message if both subject and expected are null references`` () =
fun () ->
let x = null
x.Should().NotBeSameAs(null)
|> assertExnMsg
"""
x
should not be reference equal to
null
but was the same reference.
"""


[<Fact>]
Expand Down
55 changes: 25 additions & 30 deletions src/Faqt/BasicAssertions.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
namespace Faqt

open System
open System.Runtime.CompilerServices
open AssertionHelpers
open Formatting
Expand Down Expand Up @@ -65,28 +64,26 @@ type BasicAssertions =
/// Asserts that the subject is reference equal to the specified value (which must not be null).
[<Extension>]
static member BeSameAs(t: Testable<'a>, expected: 'a, ?because) : And<'a> =
if isNull (box expected) then
raise <| ArgumentNullException(nameof expected)

use _ = t.Assert()

if isNull (box t.Subject) then
t.Fail(
"{subject}\n\tshould be reference equal to\n{0} {1}\n{2}\n\t{because}but was\nnull",
because,
(LanguagePrimitives.PhysicalHash expected).ToString(),
typeof<'a>.AssertionName,
format expected
)
elif not (LanguagePrimitives.PhysicalEquality t.Subject expected) then
if not (LanguagePrimitives.PhysicalEquality t.Subject expected) then
let expectedStr =
if isNull (box expected) then
"null"
else
$"%i{LanguagePrimitives.PhysicalHash expected} %s{expected.GetType().AssertionName}\n%s{format expected}"

let actualStr =
if isNull (box t.Subject) then
"null"
else
$"%i{LanguagePrimitives.PhysicalHash t.Subject} %s{t.Subject.GetType().AssertionName}\n%s{format t.Subject}"

t.Fail(
"{subject}\n\tshould be reference equal to\n{0} {1}\n{2}\n\t{because}but was\n{3} {4}\n{actual}",
"{subject}\n\tshould be reference equal to\n{0}\n\t{because}but was\n{1}",
because,
(LanguagePrimitives.PhysicalHash expected).ToString(),
typeof<'a>.AssertionName,
format expected,
(LanguagePrimitives.PhysicalHash t.Subject).ToString(),
t.Subject.GetType().AssertionName
expectedStr,
actualStr
)

And(t)
Expand All @@ -95,21 +92,19 @@ type BasicAssertions =
/// Asserts that the subject is not reference equal to the specified value (which must not be null).
[<Extension>]
static member NotBeSameAs(t: Testable<'a>, expected: 'a, ?because) : And<'a> =
if isNull (box expected) then
raise <| ArgumentNullException(nameof expected)

use _ = t.Assert()

if
not (isNull (box t.Subject))
&& LanguagePrimitives.PhysicalEquality t.Subject expected
then
if LanguagePrimitives.PhysicalEquality t.Subject expected then
let expectedStr =
if isNull (box expected) then
"null"
else
$"%i{LanguagePrimitives.PhysicalHash expected} %s{expected.GetType().AssertionName}\n%s{format expected}"

t.Fail(
"{subject}\n\tshould not be reference equal to\n{0} {1}\n{2}\n\t{because}but was the same reference.",
"{subject}\n\tshould not be reference equal to\n{0}\n\t{because}but was the same reference.",
because,
(LanguagePrimitives.PhysicalHash expected).ToString(),
typeof<'a>.AssertionName,
format expected
expectedStr
)

And(t)
Expand Down

0 comments on commit b8300a8

Please sign in to comment.