Reputation: 1476
I'm trying to test for the presence of a declared, defined function using the YUI3 Test framework. In Safari and FireFox, trying to use isNotUndefined, isUndefined, or isFunction fails. I expect those to throw an exception that can be handled by the test framework.
Y
Object
Y.Assert
Object
Y.Assert.isNotUndefined(x, "fail message")
ReferenceError: Can't find variable: x
Y.Assert.isUndefined(x, "fail message")
ReferenceError: Can't find variable: x
Y.Assert.isFunction(x, "fail message")
ReferenceError: Can't find variable: x
But, instead, I never get to see the failure messages, and the remainder of the tests do not run, because of the interpreter getting in the way... Doesn't that undermine the purpose of these functions, or am I misunderstanding the framework?
My intuition tells me that, given the code above and only the code above,
Y.Assert.isUndefined(x, "fail message")
should continue on without an error (because x is undeclared) and
Y.Assert.isNotUndefined(x, "fail message")
should log the message "fail message" (because x is undeclared).
However, because of the ReferenceError, there's no way (using those YUI3 methods) to test for undeclared objects. Instead, I'm left with some pretty ugly assertion code. I can't use
Y.Assert.isNotUndefined(x)
ReferenceError: Can't find variable: x
or
Y.assert( x !== undefined )
ReferenceError: Can't find variable: x
which leaves me with
Y.assert( typeof(x) !== "undefined" ) // the only working option I've found
Assert Error: Assertion failed.
which is much less readable than
Y.Assert.isNotUndefined(x)
Again, I ask: Doesn't that undermine the purpose of these functions, or am I misunderstanding the framework?
So
x
is undeclared, and so not directly testable, while
var x;
declares it, but leaves it undefined. Finally
var x = function() {};
is both declared and defined.
I think that what's missing for me is the ability to easily say
Y.Assert.isNotUndeclared(x);
-Wil
Upvotes: 0
Views: 1689
Reputation: 1476
CONTEXT: I want to be able to distinguish among:
x // undeclared && undefined
var x; // declared && undefined
var x = 5; // declared && defined
So, the challenge here is that JavaScript doesn't readily distinguish between the first 2 cases, which I wanted to be able to do for teaching purposes. After a lot of playing and reading, there does seem to be a way to do it, at least within the context of a web browser and for global variables (not great restrictions, but...):
function isDeclared(objName) {
return ( window.hasOwnProperty(objName) ) ? true : false;
}
function isDefined(objName) {
return ( isDeclared(objName) && ("undefined" !== typeof eval(objName)) ) ? true : false;
}
I realize that the use of eval could be unsafe, but for the tightly controlled context in which I would use these functions, it's OK. All others, beware and see http://www.jslint.com/lint.html
isDeclared("x") // false
isDefined("x") // false
var x;
isDeclared("x") // true
isDefined("x") // false
var x = 5;
isDeclared("x") // true
isDefined("x") // true
Upvotes: 0
Reputation: 46756
OK, was a bit late yesterday guess I understand you question now, what you want to do is to check whether a variable was defined at all, right?
The only way to do this is typeof x === 'undefined'
.
The typeof
operator allows for non-existent variables to be used with it.
So in order to it to work, you need the above expression and plug that into a normal true/false
assert.
For example (haven't used YUI3):
Y.Assert.isTrue(typeof x === 'undefined', "fail message"); // isUndefined
Y.Assert.isFalse(typeof x === 'undefined', "fail message"); // isNotUndefined
Upvotes: 2