Added support for custom object formatters

Custom object formatters allow users to customize how an object is
stringified in matcher failure messages. This can already be done by
adding a `jasmineToString` method to the objects in question. But
it's not always desirable or possible to do that, particularly when
objects of a given "type" do not inherit from a specific prototype.
For instance, suppose a web service returns a list of foos that are
deserialized from JSON, e.g.:

   { fooId: 42, /* more properties */ }

The only way to define `jasmineToString` on those is by writing code to
add it to each instance at runtime. But a custom object formatter can
recognize that the object it's looking at is a foo and format it
accordingly:

   jasmine.addCustomObjectFormatter(function(obj) {
      if (typeof obj.fooId !== 'number') {
            return undefined;
        }

        return '[Foo with ID ' + obj.fooId + ']';
    });

Unlike `jasmineToString`, custom object formatters are scoped to a
particular spec or suite and don't require any changes to the code
under test.
This commit is contained in:
Steve Gravrock
2020-01-11 14:51:12 -08:00
committed by Steve Gravrock
parent 1f23f1e4d2
commit 25816a6e77
25 changed files with 591 additions and 73 deletions

View File

@@ -97,14 +97,34 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message);
});
it("reports extra and missing properties together", function() {
it("uses custom object formatters to pretty-print properties", function() {
function formatter(x) { return '|' + x + '|'; }
var actual = {x: {y: 1, z: 2, f: 4}},
expected = {x: {y: 1, z: 2, g: 3}},
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
util = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(util),
message =
"Expected $.x to have properties\n" +
" g: 3\n" +
" g: |3|\n" +
"Expected $.x not to have properties\n" +
" f: 4";
" f: |4|";
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("uses custom object formatters to build diffs", function() {
function formatter(x) { return '|' + x + '|'; }
var actual = [{foo: 4}],
expected = [{foo: 5}],
prettyPrinter = jasmineUnderTest.makePrettyPrinter([formatter]),
util = new jasmineUnderTest.MatchersUtil({pp: prettyPrinter}),
matcher = jasmineUnderTest.matchers.toEqual(util),
message = "Expected $[0].foo = |4| to equal |5|.";
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("reports extra and missing properties of the root-level object", function() {
@@ -277,12 +297,27 @@ describe("toEqual", function() {
function Bar() {}
var actual = {x: new Foo()},
expected = {x: new Bar()},
message = "Expected $.x to be a kind of Bar, but was Foo({ }).";
expected = {x: new Bar()},
message = "Expected $.x to be a kind of Bar, but was Foo({ }).";
expect(compareEquals(actual, expected).message).toEqual(message);
});
it("uses custom object formatters to report objects with different constructors", function () {
function Foo() {}
function Bar() {}
function formatter(x) { return '|' + x + '|'; }
var actual = {x: new Foo()},
expected = {x: new Bar()},
message = "Expected $.x to be a kind of Bar, but was |[object Object]|.",
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
util = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(util);
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("reports type mismatches at the root level", function () {
function Foo() {}
function Bar() {}
@@ -803,6 +838,20 @@ describe("toEqual", function() {
expect(compareEquals(actual, expected).message).toEqual(message);
});
it("uses custom object formatters when the actual array is longer", function() {
function formatter(x) { return '|' + x + '|'; }
var actual = [1, 1, 2, 3, 5],
expected = [1, 1, 2, 3],
pp = jasmineUnderTest.makePrettyPrinter([formatter]),
util = new jasmineUnderTest.MatchersUtil({pp: pp}),
matcher = jasmineUnderTest.matchers.toEqual(util),
message = 'Expected $.length = |5| to equal |4|.\n' +
'Unexpected $[4] = |5| in array.';
expect(matcher.compare(actual, expected).message).toEqual(message);
});
it("expected array is longer", function() {
var actual = [1, 1, 2, 3],
expected = [1, 1, 2, 3, 5],