enable/disable 在 node.js 中断言语句的简单方法
Easy way to enable/disable assert statements in node.js
我在node.js中使用断言模块
https://www.npmjs.com/package/assert
在C/C++中,可以很容易地enable/disable使用宏断言语句。一般来说,node.js 和 javascript 可以做同样的事情吗?
请注意 the package you are using is adding asserts as a module and are therefor polyfills。
您可以简单地覆盖对象的 - 部分 - 以禁用 polyfill。
示例:
假设您要禁用当前看起来像这样的 deepEqual
断言:
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
您可以通过执行以下操作简单地覆盖它:
assert.deepEqual = function deepEqual(actual, expected, message) {
// disable
};
仅供参考:
断言语句正在进行中:http://wiki.ecmascript.org/doku.php?id=strawman:assert
以下是一些解决方案:
1.每次调用前测试一个全局变量
const devMode = false; // or var, if you use older javascript version
devMode && assert(...);
这在很多情况下都可以根据需要使用,但当您使用 assert
时会产生副作用,例如此处:
devMode && assert(value++, 'Value should not have been 0');
devMode && assert(myfunc(), 'myfunc unexpectedly returned false');
devMode && assert.throws(function() {
home = '/home';
throw new Error("Wrong value");
}, Error);
在上述构造中,断言调用的参数不在 devMode
中时不会被评估。所以value
不会递增,myfunc
不会被调用,home
不会被设置。
如果您使用此类构造,请查看第二种解决方案:
2。创建模拟 assert
在此解决方案中,您将创建一个与 assert
具有相同界面的库,并包含真实库或模拟库:
您的图书馆可能如下所示:
var assert = function (value, message) {
return true;
}
assert.ok = assert;
assert.fail = assert;
assert.equal = assert;
assert.notEqual = assert;
assert.deepEqual = assert;
assert.notDeepEqual = assert;
assert.strictEqual = assert;
assert.notStrictEqual = assert;
assert.ifError = assert;
// assert.throws should only be used to confirm that certain code will produce
// an error, but it should not change any state outside the function's scope.
// This mock version will NOT execute any of the functions passed to it.
assert.throws = assert;
// For assert.doesNotThrow the same choice is made:
assert.doesNotThrow = assert;
使用此解决方案,将评估传递的参数,但如果您传递函数引用,这可能仍然不够,如 assert.throws
和 assert.doesNotThrow
的情况。因此,您可能希望以不同方式实现模拟版本,以便它执行作为第一个 and/or 第二个参数传递的函数,即使在生产模式下也是如此。
3。解析您的生产代码
使用此解决方案,您的目标是从代码中删除对 assert
的任何引用。如果你只将 assert 调用用作语句,而不是表达式的一部分,并且没有你依赖的副作用(见上文),那么确保这些 assert 语句每个都在单独的一行上,并使用一个简单的grep
删除这些行。
我不会在这方面详细说明,但您可以使此解析器更智能,并且(通过使用正则表达式)让它从 assert
上下文中解包表达式。这样的解析器将替换:
assert(value++, 'Value should not have been 0')
与:
value++
使用此解决方案,无论何时在生产中部署应用程序,您都需要重复解析操作。
我在node.js中使用断言模块 https://www.npmjs.com/package/assert
在C/C++中,可以很容易地enable/disable使用宏断言语句。一般来说,node.js 和 javascript 可以做同样的事情吗?
请注意 the package you are using is adding asserts as a module and are therefor polyfills。
您可以简单地覆盖对象的 - 部分 - 以禁用 polyfill。
示例:
假设您要禁用当前看起来像这样的 deepEqual
断言:
assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual);
}
};
您可以通过执行以下操作简单地覆盖它:
assert.deepEqual = function deepEqual(actual, expected, message) {
// disable
};
仅供参考:
断言语句正在进行中:http://wiki.ecmascript.org/doku.php?id=strawman:assert
以下是一些解决方案:
1.每次调用前测试一个全局变量
const devMode = false; // or var, if you use older javascript version
devMode && assert(...);
这在很多情况下都可以根据需要使用,但当您使用 assert
时会产生副作用,例如此处:
devMode && assert(value++, 'Value should not have been 0');
devMode && assert(myfunc(), 'myfunc unexpectedly returned false');
devMode && assert.throws(function() {
home = '/home';
throw new Error("Wrong value");
}, Error);
在上述构造中,断言调用的参数不在 devMode
中时不会被评估。所以value
不会递增,myfunc
不会被调用,home
不会被设置。
如果您使用此类构造,请查看第二种解决方案:
2。创建模拟 assert
在此解决方案中,您将创建一个与 assert
具有相同界面的库,并包含真实库或模拟库:
您的图书馆可能如下所示:
var assert = function (value, message) {
return true;
}
assert.ok = assert;
assert.fail = assert;
assert.equal = assert;
assert.notEqual = assert;
assert.deepEqual = assert;
assert.notDeepEqual = assert;
assert.strictEqual = assert;
assert.notStrictEqual = assert;
assert.ifError = assert;
// assert.throws should only be used to confirm that certain code will produce
// an error, but it should not change any state outside the function's scope.
// This mock version will NOT execute any of the functions passed to it.
assert.throws = assert;
// For assert.doesNotThrow the same choice is made:
assert.doesNotThrow = assert;
使用此解决方案,将评估传递的参数,但如果您传递函数引用,这可能仍然不够,如 assert.throws
和 assert.doesNotThrow
的情况。因此,您可能希望以不同方式实现模拟版本,以便它执行作为第一个 and/or 第二个参数传递的函数,即使在生产模式下也是如此。
3。解析您的生产代码
使用此解决方案,您的目标是从代码中删除对 assert
的任何引用。如果你只将 assert 调用用作语句,而不是表达式的一部分,并且没有你依赖的副作用(见上文),那么确保这些 assert 语句每个都在单独的一行上,并使用一个简单的grep
删除这些行。
我不会在这方面详细说明,但您可以使此解析器更智能,并且(通过使用正则表达式)让它从 assert
上下文中解包表达式。这样的解析器将替换:
assert(value++, 'Value should not have been 0')
与:
value++
使用此解决方案,无论何时在生产中部署应用程序,您都需要重复解析操作。