From c1b483c8c4d3f58677bacc106be13708dd73ef75 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 9 Sep 2016 23:05:46 -0700 Subject: [PATCH] =?UTF-8?q?[Fix]=20`throws`:=20only=20reassign=20=E2=80=9C?= =?UTF-8?q?message=E2=80=9D=20when=20it=20is=20not=20already=20non-enumera?= =?UTF-8?q?ble.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #320. --- lib/test.js | 10 +++++++--- test/throws.js | 25 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/lib/test.js b/lib/test.js index 9611dd25..538cbcdd 100644 --- a/lib/test.js +++ b/lib/test.js @@ -5,6 +5,8 @@ var inherits = require('inherits'); var EventEmitter = require('events').EventEmitter; var has = require('has'); var trim = require('string.prototype.trim'); +var bind = require('function-bind'); +var isEnumerable = bind.call(Function.call, Object.prototype.propertyIsEnumerable); module.exports = Test; @@ -444,9 +446,11 @@ Test.prototype['throws'] = function (fn, expected, msg, extra) { fn(); } catch (err) { caught = { error : err }; - var message = err.message; - delete err.message; - err.message = message; + if (!isEnumerable(err, 'message') || !has(err, 'message')) { + var message = err.message; + delete err.message; + err.message = message; + } } var passed = caught; diff --git a/test/throws.js b/test/throws.js index 1867aa84..77273d43 100644 --- a/test/throws.js +++ b/test/throws.js @@ -93,10 +93,14 @@ tap.test('failures', function (tt) { + ' operator: throws\n' + ' expected: undefined\n' + ' actual: undefined\n' - + ' ...\n\n' - + '1..9\n' - + '# tests 9\n' - + '# pass 0\n' + + ' ...\n' + + '# custom error messages\n' + + 'ok 10 "message" is enumerable\n' + + "ok 11 { custom: 'error', message: 'message' }\n" + + 'ok 12 getter is still the same\n' + + '\n1..12\n' + + '# tests 12\n' + + '# pass 3\n' + '# fail 9\n' ); })); @@ -117,4 +121,17 @@ tap.test('failures', function (tt) { t.plan(1); t.throws(function () {}); }); + + test('custom error messages', function (t) { + t.plan(3); + var getter = function () { return 'message'; }; + var messageGetterError = Object.defineProperty( + { custom: 'error' }, + 'message', + { configurable: true, enumerable: true, get: getter } + ); + t.equal(Object.prototype.propertyIsEnumerable.call(messageGetterError, 'message'), true, '"message" is enumerable'); + t.throws(function () { throw messageGetterError; }, "{ custom: 'error', message: 'message' }"); + t.equal(Object.getOwnPropertyDescriptor(messageGetterError, 'message').get, getter, 'getter is still the same'); + }); });