From 4fc177d5ae378346aef05f408f5edadef68823cd Mon Sep 17 00:00:00 2001 From: ksvitkovsky Date: Tue, 1 Aug 2017 23:58:33 +0400 Subject: [PATCH] Better pretty printing for typed arrays --- spec/core/matchers/toEqualSpec.js | 10 ++++++++++ spec/helpers/checkForTypedArrays.js | 20 ++++++++++++++++++++ spec/support/jasmine.json | 1 + spec/support/jasmine.yml | 1 + src/core/PrettyPrinter.js | 14 ++++++++++++++ src/core/base.js | 16 +++++++++++++++- 6 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 spec/helpers/checkForTypedArrays.js diff --git a/spec/core/matchers/toEqualSpec.js b/spec/core/matchers/toEqualSpec.js index fc4726cb..ba0457ac 100644 --- a/spec/core/matchers/toEqualSpec.js +++ b/spec/core/matchers/toEqualSpec.js @@ -211,6 +211,16 @@ describe("toEqual", function() { expect(compareEquals(actual, expected).message).toEqual(message); }); + it("reports mismatches between arrays of different types", function() { + jasmine.getEnv().requireFunctioningTypedArrays(); + + var actual = new Uint32Array([1, 2, 3]), + expected = new Uint16Array([1, 2, 3]), + message = "Expected Uint32Array [ 1, 2, 3 ] to equal Uint16Array [ 1, 2, 3 ]."; + + expect(compareEquals(actual, expected).message).toEqual(message); + }); + it("reports mismatches involving NaN", function() { var actual = {x: 0}, expected = {x: 0/0}, diff --git a/spec/helpers/checkForTypedArrays.js b/spec/helpers/checkForTypedArrays.js new file mode 100644 index 00000000..ddbdcc9f --- /dev/null +++ b/spec/helpers/checkForTypedArrays.js @@ -0,0 +1,20 @@ +(function(env) { + function hasFunctioningTypedArrays() { + if (typeof Uint32Array === 'undefined') { return false; } + + try { + var a = new Uint32Array([1, 2, 3]); + if (a.length !== 3) { return false; } + return true; + } catch(e) { + return false; + } + } + + env.requireFunctioningTypedArrays = function() { + if (!hasFunctioningTypedArrays()) { + env.pending("Browser has incomplete or missing support for typed arrays"); + } + }; + +})(jasmine.getEnv()); diff --git a/spec/support/jasmine.json b/spec/support/jasmine.json index 82a31b2d..604af59c 100644 --- a/spec/support/jasmine.json +++ b/spec/support/jasmine.json @@ -9,6 +9,7 @@ "helpers/asyncAwait.js", "helpers/checkForSet.js", "helpers/checkForMap.js", + "helpers/checkForTypedArrays.js", "helpers/nodeDefineJasmineUnderTest.js" ], "random": true diff --git a/spec/support/jasmine.yml b/spec/support/jasmine.yml index 5dc91c36..637b00eb 100644 --- a/spec/support/jasmine.yml +++ b/spec/support/jasmine.yml @@ -20,6 +20,7 @@ helpers: - 'helpers/BrowserFlags.js' - 'helpers/checkForSet.js' - 'helpers/checkForMap.js' + - 'helpers/checkForTypedArrays.js' - 'helpers/defineJasmineUnderTest.js' spec_files: - '**/*[Ss]pec.js' diff --git a/src/core/PrettyPrinter.js b/src/core/PrettyPrinter.js index 5df4166a..16b66074 100644 --- a/src/core/PrettyPrinter.js +++ b/src/core/PrettyPrinter.js @@ -40,6 +40,8 @@ getJasmineRequireObj().pp = function(j$) { this.emitSet(value); } else if (j$.getType_(value) == '[object Map]') { this.emitMap(value); + } else if (j$.isTypedArray_(value)) { + this.emitTypedArray(value); } else if (value.toString && typeof value === 'object' && !j$.isArray_(value) && hasCustomToString(value)) { this.emitScalar(value.toString()); } else if (j$.util.arrayContains(this.seen, value)) { @@ -210,6 +212,18 @@ getJasmineRequireObj().pp = function(j$) { this.append(' })'); }; + StringPrettyPrinter.prototype.emitTypedArray = function(arr) { + var constructorName = j$.fnNameFor(arr.constructor), + limitedArray = Array.prototype.slice.call(arr, 0, j$.MAX_PRETTY_PRINT_ARRAY_LENGTH), + itemsString = Array.prototype.join.call(limitedArray, ', '); + + if (limitedArray.length !== arr.length) { + itemsString += ', ...'; + } + + this.append(constructorName + ' [ ' + itemsString + ' ]'); + }; + StringPrettyPrinter.prototype.formatProperty = function(obj, property, isGetter) { this.append(property); this.append(': '); diff --git a/src/core/base.js b/src/core/base.js index 949f9f29..98ff3e91 100644 --- a/src/core/base.js +++ b/src/core/base.js @@ -63,6 +63,18 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return j$.isA_('AsyncFunction', value); }; + j$.isTypedArray_ = function(value) { + return j$.isA_('Float32Array', value) || + j$.isA_('Float64Array', value) || + j$.isA_('Int16Array', value) || + j$.isA_('Int32Array', value) || + j$.isA_('Int8Array', value) || + j$.isA_('Uint16Array', value) || + j$.isA_('Uint32Array', value) || + j$.isA_('Uint8Array', value) || + j$.isA_('Uint8ClampedArray', value); + }; + j$.isA_ = function(typeName, value) { return j$.getType_(value) === '[object ' + typeName + ']'; }; @@ -80,7 +92,9 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) { return func.name; } - var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/); + var matches = func.toString().match(/^\s*function\s*(\w*)\s*\(/) || + func.toString().match(/^\s*\[object\s*(\w*)Constructor\]/); + return matches ? matches[1] : ''; };