power-assert
power-assert copied to clipboard
More descriptive results for `typeof` expressions
So, something like this is a pretty common pattern:
assert(typeof wrap === 'function')
AssertionError: # giraphe.es6.js:61
assert(typeof wrap === 'function')
| |
"object" false
--- [string] 'function'
+++ [string] typeof wrap
@@ -1,8 +1,6 @@
-function
+object
+ expected - actual
-false
+true
Although this works, I feel that this could easily be extended with more useful information: for instance, in most failing assertions, there's information about the object under test; but specifically in typeof's case, that gets lost, and it gets treated as a simple comparison of two static strings.
Here's something like what I'd expect to see (hastily cobbled together from the results for assert(wrap === 'function'), because it was an easy change :P:
AssertionError: # giraphe.es6.js:61
assert(typeof wrap === 'function')
| | |
| | false
| Object{}
"object"
[string] 'function'
=> "function"
[Object] wrap
=> Object{}
--- [string] 'function'
+++ [string] typeof wrap
@@ -1,8 +1,6 @@
-function
+object
+ expected - actual
-false
+true
Thank you for your question.
Unfortunately, it's a limitation of current implementation of power-assert. I cannot support typeof UnaryExpression since it potentially causes ReferenceError.
Let me explain. Given example.js,
var obj = {
name: 'foo'
};
function capt (val) {
return val;
}
console.log(typeof obj); //=> 'object'
console.log(typeof capt(obj)); //=> 'object'
console.log(typeof doesNotExist); //=> 'undefined'
console.log(typeof capt(doesNotExist)); //=> ReferenceError: doesNotExist is not defined
results in ReferenceError when executed. Since typeof operator can take variable that does not defined.
$ node explain.js
object
object
undefined
/Users/takuto/src/github.com/power-assert-js/power-assert/explain.js:13
console.log(typeof capt(doesNotExist)); //=> ReferenceError: doesNotExist is not defined
^
ReferenceError: doesNotExist is not defined
at Object.<anonymous> (/Users/takuto/src/github.com/power-assert-js/power-assert/explain.js:13:25)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:456:32)
at tryModuleLoad (module.js:415:12)
at Function.Module._load (module.js:407:3)
at Function.Module.runMain (module.js:575:10)
at startup (node.js:160:18)
at node.js:445:3
$
capt function is the simplest mimic of what power-assert is doing internally, so when I tried to capture typeof UnaryExpression like typeof foo, it always result in ReferenceError.
Since test tool should not change behavior of SUT (System Under Test), I gave up supporting typeof UnaryExpression.
Sorry for inconvenience. I'll write about this limitation to FAQ section in REAME. Thanks!
Wait, tho: can't you special-case typeof at the syntactic level?
i.e. anything else in JS becomes expr(expr(expr)) to
capt(expr(capt(expr(capt(expr))))) … of course, that makes sense; but
typeof is special, so it makes sense to special-case it: expr(typeof expr)) to capt(expr(capt(typeof expr !== 'undefined' && typeof capt(expr) or something like that
Sorry for being terse, am on phone. Let me know if confused, can re-explain when at computer! On Fri, Jun 10, 2016 at 4:08 AM Takuto Wada [email protected] wrote:
Thank you for your question.
Unfortunately, it's a limitation of current implementation of power-assert. I cannot support typeof UnaryExpression since it potentially causes ReferenceError.
Let me explain. Given example.js,
var obj = { name: 'foo' }; function capt (val) { return val; } console.log(typeof obj); //=> 'object'console.log(typeof capt(obj)); //=> 'object' console.log(typeof doesNotExist); //=> 'undefined'console.log(typeof capt(doesNotExist)); //=> ReferenceError: doesNotExist is not defined
results in ReferenceError when executed. Since typeof operator can take variable that does not defined.
$ node explain.js object object undefined /Users/takuto/src/github.com/power-assert-js/power-assert/explain.js:13 console.log(typeof capt(doesNotExist)); //=> ReferenceError: doesNotExist is not defined ^
ReferenceError: doesNotExist is not defined at Object.
(/Users/takuto/src/github.com/power-assert-js/power-assert/explain.js:13:25) at Module._compile (module.js:541:32) at Object.Module._extensions..js (module.js:550:10) at Module.load (module.js:456:32) at tryModuleLoad (module.js:415:12) at Function.Module._load (module.js:407:3) at Function.Module.runMain (module.js:575:10) at startup (node.js:160:18) at node.js:445:3 $ capt function is what power-assert is doing internally, so when I tried to capture typeof UnaryExpression like typeof foo, it always result in ReferenceError.
Since test tool should not change behavior of SUT (System Under Test), I gave up supporting typeof UnaryExpression.
Sorry for inconvenience. I'll write about this limitation to FAQ section in REAME. Thanks!
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/power-assert-js/power-assert/issues/60#issuecomment-225130851, or mute the thread https://github.com/notifications/unsubscribe/AAAAyLCpy5K5DD3F3w_aJSkHrQGOctSaks5qKSlrgaJpZM4IpEzA .
Ah, immediately realized a problem with that, so pulled out my laptop after sending.
Here's the two solutions I see:
// foo( typeof bar )
var _t; capt(foo( (((_t = typeof bar) !== 'undefined' && capt(bar)), _t)))
That's fast, but the downside is that it evaluates bar twice; so it's only suitable for situations where bar is not a complicated expression: i.e. it's just a standalone identifier.
Now, I'm not convinced anything except a standalone identifier can trigger a ReferenceError, will need to check the spec, but if it can, then more complicated expressions can be transformed to:
// foo( typeof bar(widget widget widget) )
var _a, _b; _a = capt(widget widget widget); try { _b = capt_maybe(bar(_a)) }
catch (e) { _b = capt_fail() }; capt(foo(_b))
… or something like that, I got bogged down halfway through trying to construct it.
I think I've said this elsewhere on this project, but just to iterate: I'm totally aware that this looks like a ton of work. Special-casing in the parser, special-casing in the generator, special-casing capturing-functions that may not be evaluated (in the case of the try/catch approach), it's all a mess. I do disagree with you in that I think it's possible, but “this is too much work right now, and is outside the scope of this project, I'm afraid” is an answer I'm prepared to accept. (=
Resurrecting — any input on my suggestions, @twada? I wouldn't mind submitting a pull-request for one of my solutions (whichever you prefer), if this behaviour is welcome.
@ELLIOTTCABLE Thank you for resurrecting this issue.
This is in my someday task. Sorry for my late response.
I think the solution might be look like babel's typeof helper. Could be a bit simpler.