Search code examples
javascripttddyui3

How to use Assert.isUndefined() and Assert.isNotUndefined() in YUI3?


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


Solution

  • 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