Subversion Repositories JSX

Compare Revisions

Last modification

Ignore whitespace Rev 139 → Rev 140

/trunk/test/debug.js
6,7 → 6,7
* @partof PointedEars' JavaScript Extensions (JSX)
*
* @section Copyright & Disclaimer
*
*
* @author
* (C) 2001-2009 Thomas Lahn <debug.js@PointedEars.de>
*/
34,7 → 34,7
* program (COPYING file); if not, go to [1] or write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*
*
* [1] <http://www.gnu.org/licenses/licenses.html#GPL>
*/
 
43,7 → 43,7
this[sGlobal] = this;
 
// global undefined value (for implementations without it)
var undefined = _global.undefined;
var undefined;
 
/** @section Exceptions */
 
93,39 → 93,42
};
}
 
/**
* @param sExpression : string
* @param sTest : string
* @param expected
* @return mixed
*/
function test2(sExpression, sTest, expected)
if (typeof test2 == "undefined")
{
var out = new Array(), result;
/**
* @param sExpression : string
* @param sTest : string
* @param expected
* @return mixed
*/
var test2 = function(sExpression, sTest, expected)
{
var out = new Array(), result;
if (sExpression) out.push(sExpression);
if (sExpression) out.push(sExpression);
 
setErrorHandler();
eval(new Array(
'try {',
' eval(sExpression.replace(/\\bvar\\s+/g, ""));',
' try {',
' result = eval(sTest.replace(/\\bvar\\s+/g, ""));',
" out.push('// ' + sTest + ' === ' + result",
" + ' (expected: ' + expected + ')');",
' } catch(e) {',
" out.push('// ' + sTest + ' \\u21d2 ' + e.name + ': '",
" + e.message);",
' }',
'} catch(e) {',
" out.push('// ' + sExpression + ' \\u21d2 ' + e.name + ': '",
" + e.message);",
'}').join("\n"));
clearErrorHandler();
document.write(out.join('\n') + '\n\n');
return result;
setErrorHandler();
eval(new Array(
'try {',
' eval(sExpression.replace(/\\bvar\\s+/g, ""));',
' try {',
' result = eval(sTest.replace(/\\bvar\\s+/g, ""));',
" out.push('// ' + sTest + ' === ' + result",
" + ' (expected: ' + expected + ')');",
' } catch(e) {',
" out.push('// ' + sTest + ' \\u21d2 ' + e.name + ': '",
" + e.message);",
' }',
'} catch(e) {',
" out.push('// ' + sExpression + ' \\u21d2 ' + e.name + ': '",
" + e.message);",
'}').join("\n"));
clearErrorHandler();
document.write(out.join('\n') + '\n\n');
return result;
};
}
/*
var o;
168,7 → 171,7
/**
* Asserts that a condition is true. If it isn't, it throws
* an <code>AssertionError</code> with a default message.
*
*
* @param x : string|any
* If a string, it is evaluated as a <i>Program</i>; the assertion
* fails if its result, type-converted to <i>boolean</i>, is
175,7 → 178,7
* <code>false</code>.
* If not a string, the value is type-converted to <i>boolean</i>;
* the assertion fails if the result of the conversion is
* <code>false</code>.
* <code>false</code>.
* @throws
* <code>AssertionError</code> if the assertion fails and this exception
* can be thrown.
208,7 → 211,7
/**
* Asserts that a condition is false. If it isn't, it throws
* an <code>AssertionError</code> with a default message.
*
*
* @param x : string|any
* If a string, it is evaluated as a <i>Program</i>; the assertion
* fails if its result, type-converted to <i>boolean</i>, is
215,7 → 218,7
* <code>true</code>.
* If not a string, the value is type-converted to <i>boolean</i>;
* the assertion fails if the result of the conversion is
* <code>true</code>.
* <code>true</code>.
* @throws
* <code>AssertionError</code> if the assertion fails and this exception
* can be thrown.
253,7 → 256,7
* an <code>AssertionError</code> is thrown with a default message.
* Two arrays are considered equal only if their elements are
* strictly equal (shallow strict comparison).
*
*
* @param expecteds : string|Array
* Expected value; if a string, it is evaluated as a <i>Program</i>.
* @param actuals : string|Array
261,11 → 264,11
* @throws
* <code>ArrayComparisonFailure</code> if either of the given
* values is not a reference to an Array object;
*
* <code>AssertionError</code>
*
* <code>AssertionError</code>
* if the assertion fails and either exception can be thrown.
* @type boolean
* @return
* @return
* <code>false</code>, if comparison is not possible
* or the assertion fails, and no exception can be thrown;
* <code>true</code>, if the assertion is met.
272,7 → 275,7
* @see eval()
*/
var assertArrayEquals = function(expecteds, actuals) {
if (typeof expecteds == "string") expecteds = eval(expecteds);
if (typeof expecteds == "string") expecteds = eval(expecteds);
if (typeof actuals == "string") actuals = eval(actuals);
if (expecteds == null && actuals == null)
308,7 → 311,7
stack.shift();
stack.shift();
stack = stack.join("\n");
}
}
eval('throw new AssertionError('
+ '"assertArrayEquals([" + expecteds + "], [" + actuals + "]);'
344,15 → 347,15
// descr = profile.description,
// msg = (descr ? (descr + ": ") : "") + (new Date() - profile.start)
// + " ms";
//
//
// if (isMethod("window", "alert"))
// {
// window.alert(msg);
// }
//
//
// delete profile.start;
// delete profile.description;
//
//
// return msg;
// };
// }
360,10 → 363,10
 
/**
* Returns evaluation statistics.
*
*
* @param expr : string|Array
* Expression or array of expressions to be evaluated.
* @param bPrintResult : optional boolean = false
* @param bPrintResult : optional boolean = false
* If <code>true</code>, the method returns a printable result.
* @param loops : optional number = 1
* Specifies the number of times the expression should be evaluated.
398,7 → 401,7
result = ["Expressions:\n\n"],
stats = [];
 
// loop through expressions
/* loop through expressions */
for (var i = 0, cnt = expr.length; i < cnt; i++)
{
var cur_expr = expr[i];
407,36 → 410,34
result.push("[", i + 1, "] ", cur_expr, "\n");
}
// reset stats for this expression
/* reset stats for this expression */
var repeat_stats = stats[i] = [];
// repeat loops
/* repeat loops */
for (var j = 0; j < repeats; j++)
{
// reset stats for this repeat
/* reset stats for this repeat */
repeat_stats[j] = -1;
var eval_loop_start = new Date();
// repeat evaluation
/* repeat evaluation */
for (var k = 0; k < loops; k++)
{
setErrorHandler();
eval(["try {", expr[i], "} catch (e) {}"].join(""));
clearErrorHandler();
jsx.tryThis(function() { expr[i]; });
}
var eval_loop_stop = new Date();
repeat_stats[j] = eval_loop_stop.getTime() - eval_loop_start.getTime();
repeat_stats[j] = new Date() - eval_loop_start;
}
}
 
if (bPrintResult)
{
debugger;
result.push(
"\nEvaluation Results (ms):\n\n\\",
pad("n|", cnt.toString().length - 1));
var col_width = Math.max(repeats, stats).toString().length + 1;
var col_width = Math.maxN(repeats, stats).toString().length + 1;
for (j = 0; j < repeats; j++)
{
463,9 → 464,9
result.push(
format(
"\xA0%*4$s\xA0%*4$s\xA0%*4$s\n",
Math.min(stats[i]),
Math.max(stats[i]),
Math.avg(stats[i]).toFixed(1),
Math.minN(stats[i]),
Math.maxN(stats[i]),
Math.avgN(stats[i]).toFixed(1),
col_width));
}
480,9 → 481,9
}
 
/**
* @param e : Error
* @param e : Error
* @return string
*/
*/
function getError(e)
{
var sError = e;
531,48 → 532,11
return sError;
}
 
/**
* Print to Firebug console.
* printfire() courtesy of Joe Hewitt, extension creator.
* <URL:http://www.joehewitt.com/software/firebug/>
*
* @params
* @return undefined
*/
function dmsg()
{
// Firebug 0.4+
if (isMethod("console", "log"))
{
console.log.apply(console, arguments);
}
// Firebug before 0.4
else if (isMethod("document", "createEvent")
&& isMethod("document", "dispatchEvent"))
{
printfire.args = arguments;
var ev = document.createEvent("Events");
if (ev)
{
jsx.tryThis(
/**
* @return undefined
*/
function() {
ev.initEvent("printfire", false, true);
dispatchEvent(ev);
});
}
}
}
var printfire = dmsg;
 
/**
* Returns the type of a reference and, if possible, of its object properties
* (nested only one level deep), and optionally displays that in an alert()
* box.
*
*
* @param a
* Value to be displayed along with its type. If a string or an array of
* strings and bDontEval is not provided or false, each string is evaluated
628,7 → 592,7
 
/*
* JavaScript Beautifier and Uglyfier ;-)
*
*
* Test input:
 
javascript:
681,8 → 645,8
 
/**
* @param s : string
* @return string
*/
* @return string
*/
function uglyfy(s)
{
return s.replace(/\s/g, " "); // .replace
745,7 → 709,7
"typeof", "delete", "instanceof",
"i[fn]", "else",
"switch", "case", "break", "default",
"do", "for( +each)?", "while",
"do", "for( +each)?", "while",
"try", "catch", "finally", "throw",
"let", "yield",
"expando", "hide", "override"
756,7 → 720,7
"__iterator__", "__proto__", "constructor", "hasOwnProperty",
"isPrototypeOf", "propertyIsEnumerable",
"Array", "concat", "every", "indexOf", "join", "length", "pop", "push",
"reverse", "shift", "slice", "some", "sort", "splice", "unshift",
"reverse", "shift", "slice", "some", "sort", "splice", "unshift",
"Boolean",
"Date", "getFullYear", "getMilliseconds", "getUTCDate", "getUTCDay",
"getUTCFullYear", "getUTCHours", "getUTCMilliseconds", "getUTCMinutes",
779,7 → 743,7
"VBArray",
"XMLHttpRequest",
"document", "write",
"window", "clearInterval", "clearTimeout", "setInterval", "setTimeout"
"window", "clearInterval", "clearTimeout", "setInterval", "setTimeout"
],
rxCode = new RegExp(
"(//.*|/\\*(.|\\s)*?\\*/)"
797,7 → 761,7
aReplace = [
[ 1, 'comm'],
[ 4, 'scr'],
[ 7, 'regexp'],
[ 7, 'regexp'],
[ 9, 'tag'],
[11, 'str'],
[14, 'entity'],
819,7 → 783,7
if (arguments[r[0]])
{
match = '<span class="' + r[1] + '">' + match + '<\/span>';
break;
break;
}
}
 
841,7 → 805,7
}
}
else if (node.nodeType == Node.TEXT_NODE)
{
{
var v = node.nodeValue;
var m = v.match(needle);
if (m)
923,7 → 887,7
* provide an identifier for the property with <code>iID</code>
* and an array of references to the owner objects with
* <code>aoOwners</code>.
*
*
* If you provide the latter, the constructor function will
* utilize <code>inArray()</code>, trying to determine if the
* object/property references one of owners
945,7 → 909,7
* to count non-enumerable properties of a property; it seemed
* ineffective to copypaste the ObjectInfo(...) code into this
* constructor, thus the cross-calling.)
*
*
* For reasons of backwards compatibility the object also provides
* the `referencesOwner' property to specify if it references
* its direct owner and allows for passing an object reference
954,24 → 918,24
* <code>aoOwners</code> is an Owners object or not, the
* <code>isInstanceOf()</code> method is required.
*
* @param sName : string
* @param sName : string
* Name of the property.
* @param sValue
* Value of the property.
* @param iID : optional number
* (Unique) ID of the property.
* @param aoOwners : optional Owners|Object
* @param aoOwners : optional Owners|Object
* Reference to an Owners object storing references to the
* owner (object) of the property and its owners, where the
* last element references the direct owner. Allows also
* for a reference to a non-Owners object to specify only
* the direct owner.
* @param bNonEnum : optional boolean
* @param bNonEnum : optional boolean
* <code>true</code> specifies that the property is
* non-enumerable. Optional. The default <code>false</code>
* determines the property to be enumerable.
* @param bCalledFromObjectInfo : optional boolean
* @return undefined
* @return undefined
* @see types.js:isArray(), array.js:inArray()
*/
function Property(sName, sValue, iID, aoOwners, bNonEnum,
1081,13 → 1045,13
* The current sort order and direction is stored in the
* `sortOrder' and `sortDir' properties of the `properties'
* extended Array object.
*
*
* For the sort direction constants are the negative opposite
* of each other, you may toggle the sort direction easily:
*
* var p = bar.properties;
* p.sortBy(p.sortOrder, -p.sortDir);
*
*
* If `sortDir' was `0' (zero) before and therefore the
* properties were unsorted (i.e. sorted by ID), the array
* will then be sorted ascending by the current criteria.
1106,7 → 1070,7
*
* @param oProperty : Property
* @return number|Property
*/
*/
PropertyArray.prototype.push =
function propertyArray_push(oProperty)
{
1117,7 → 1081,7
* With a reference to an ObjectInfo object having a valid
* `target' reference, you may sort the property array by
* properties of the Property prototype:
*
*
* if (bar && bar.properties)
* {
* bar.properties.unsort();
1137,10 → 1101,10
* sortById(sdAscending).
*/
// Specific sort methods
/** @type Comparator */
/** @type Comparator */
PropertyArray.prototype.cmpSortByIdAsc =
new Function("a", "b", "return a.id - b.id;");
/** @type Comparator */
/** @type Comparator */
PropertyArray.prototype.cmpSortByIdDesc =
new Function("a", "b", "return b.id - a.id;");
 
1196,7 → 1160,7
* @param b : Property
* @type Comparator
* @return number
*/
*/
PropertyArray.prototype.cmpSortByNameDesc =
function propertyArray_cmpSortByNameDesc(a, b)
{
1239,7 → 1203,7
/**
* @param a : Property
* @param b : Property
* @type Comparator
* @type Comparator
* @return number
*/
PropertyArray.prototype.cmpSortByTypeAsc =
1307,7 → 1271,7
/**
* @param a : Property
* @param b : Property
* @type Comparator
* @type Comparator
* @return number
*/
PropertyArray.prototype.cmpSortByValueAsc =
1331,7 → 1295,7
/**
* @param a : Property
* @param b : Property
* @type Comparator
* @type Comparator
* @return number
*/
PropertyArray.prototype.cmpSortByValueDesc =
1379,7 → 1343,7
* arguments, the first defining the sort criteria, the
* second the sort direction. You are recommended to use
* the sort order and direction constants for arguments:
*
*
* var p = bar.properties;
* p.sortBy(p.soByName, p.sdDescending);
*
1388,7 → 1352,7
* invalid value causes no error, but the array not to be
* re-sorted.
*
* @param iSortOrder : optional number
* @param iSortOrder : optional number
* Sort order.
* @param iSortDir : optional number
* Sort direction.
1418,10 → 1382,10
};
 
/**
* @param sName : string
* @param sValue : _
* @param iID : optional number
* @param oOwner : optional Object
* @param sName : string
* @param sValue : _
* @param iID : optional number
* @param oOwner : optional Object
* @param bNonEnum : optional boolean
* @param bCalledFromProperty : optional boolean
* @return undefined
1434,7 → 1398,7
if ((isMethodType(typeof this.items.hasOwnProperty)
// IE does not allow reference shortcut here!
&& this.items.hasOwnProperty != null
&& !this.items.hasOwnProperty(sName))
&& !this.items.hasOwnProperty(sName))
|| (!isMethodType(typeof this.items.hasOwnProperty)
&& typeof this.items[sName] == "undefined"))
{
1452,7 → 1416,7
if ((bMethod && !this.items.hasOwnProperty(sName))
|| (!bMethod && typeof this.items[sName] == "undefined"))
{
this.items[sName] = sValue;
this.items[sName] = sValue;
}
 
this.length = this.items.length;
1460,8 → 1424,8
};
 
/**
* @param rxPattern : RegExp
* @param asPropertyNames : [string]
* @param rxPattern : RegExp
* @param asPropertyNames : [string]
* @param sType : optional string
* @param fConstructor : optional Object
* @return undefined
1468,7 → 1432,7
*/
function NonEnumProperties(rxPattern, asPropertyNames, sType, fConstructor)
{
this.pattern = rxPattern || new RegExp(".");
this.pattern = rxPattern || new RegExp(".");
this.names = asPropertyNames || new Array();
this.type = sType || "";
this.fConstructor = fConstructor || null;
1481,14 → 1445,14
* <code>name</code>, <code>type</code> and <code>value</code>
* of the <code>Property</code> prototype. [See the sort
* methods defined in the <code>forObject(...)</code> method.]
*
*
* Requires JavaScript 1.5+ for inline <code>function</code>
* statement (1.2+) and <code>try...catch</code> statement (1.5+).
*
* Usage:
*
*
* <code>var foo = new ObjectInfo(myObject, sMyObjectName);</code>
*
*
* whereas <code>foo</code> is then a reference to the
* <code>ObjectInfo</code> object containing property
* information about the object referenced by
1495,13 → 1459,13
* <code>myObject</code> or the object evaluated from
* it (so that the argument can be a string, therefore
* <code><strong>s</strong>Object</code>.)
*
*
* The <code>foo.name</code> property contains the name of the
* string to be evaluated to an object. However, if you pass a
* reference for first argument or want to fake the object's
* name for some reason, you may pass a string for the second
* argument in order to overwrite the default (see below.)
*
*
* Note that it is also tried to retrieve known but non-enumerable
* properties if either <code>sObject</code> is a string or
* <code>sName</code> is a string, matching either value against a
1520,18 → 1484,18
*
* Otherwise, <code>foo.target</code> is a reference to the
* object which properties are accessed by <code>foo</code>:
*
*
* <code>
* if (foo && foo.target && foo.target == anyOtherObject)
* alert("anyOtherObject references myObject.");
* </code>
*
* @param sObject : string|Object
* @param sObject : string|Object
* Reference to an object or property, or string to be evaluated
* to an object or a property.
* (TODO: Throws NotAnObjectException if not provided or cannot
* be evaluated.)
* @param sName : optional string
* @param sName : optional string
* Name of the object/property.
* If this argument is not provided, the value of the
* <code>name</code> property depends on <code>sObject</code>.
1555,7 → 1519,7
* if (foo)
* foo.forObject(myOtherObject);
* </code>
*
*
* The <code>forObject(...)</code> method returns
* <code>null</code> as well if <code>myOtherObject</code>
* cannot be evaluated to an object, otherwise a reference
1562,7 → 1526,7
* to the <code>ObjectInfo</code> object. In the first case
* the properties of the former <code>ObjectInfo</code> object
* are preserved:
*
*
* <code>
* var myObject = new Something(...);
* ...
1578,16 → 1542,16
* alert(foo.toString());
* }
* </code>
*
* @param sObject: string|Object
*
* @param sObject: string|Object
* See contract of this()
* @param sName: optional string
* @param sName: optional string
* See contract of this()
* @param bCalledFromProperty: optional boolean
* @property name: string
* @property properties: PropertyArray
* @property target: object
* @property type: string
* @param bCalledFromProperty: optional boolean
* @property name: string
* @property properties: PropertyArray
* @property target: object
* @property type: string
*/
ObjectInfo.prototype.aStringProperties = [
"length", "anchor", "big", "blink", "bold", "charAt", "charCodeAt",
1643,7 → 1607,7
"getMinutes", "getMonth", "getSeconds", "getTime",
"getTimezoneOffset", "getUTCDate", "getUTCDay", "getUTCFullYear",
"getUTCHours", "getUTCMilliseconds", "getUTCMinutes",
"getUTCMonth", "getUTCSeconds", "getYear",
"getUTCMonth", "getUTCSeconds", "getYear",
"parse", "setDate",
"setFullYear", "setHours", "setMilliseconds", "setMinutes",
"setMonth", "setSeconds", "setTime", "setUTCDate", "setUTCFullYear",
1833,7 → 1797,7
}
// Retrieve non-enumerable properties by guessing them
/** @property boolean */ this.hasNonEnumProperties = false;
/** @property boolean */ this.hasNonEnumProperties = false;
for (i = this.aNonEnumProperties.length; i--; 0)
{
1882,7 → 1846,7
true); // is non-enumerable
}
}
}
}
}
this.hasProperties = (this.properties.length > 0);
1905,7 → 1869,7
* @return PropertyArray
* An array with the data of all properties that
* match the passed conditions as elements.
*/
*/
getProperties: function(rxName, rxType, bInvert, aValue)
{
if (typeof rxType == "string")
1985,13 → 1949,13
var CH_NBSP = unescape("%A0");
 
/**
* @param sObject : string|Object
* @param aWhat : optional string|RegExp
* @param sStyle : optional string
* @param sHeader : optional string
* @param sFooter : optional string
* @param sObject : string|Object
* @param aWhat : optional string|RegExp
* @param sStyle : optional string
* @param sHeader : optional string
* @param sFooter : optional string
* @param sInspectorPath : optional string
* @return string
* @return string
*/
function getObjInfo(sObject, aWhat, sStyle, sHeader, sFooter, sInspectorPath)
{
2024,7 → 1988,7
' }',
+ '}').join("\n"));
clearErrorHandler();
if (! tc)
if (! tc)
{
o = eval(sObject);
// alert("7: " + "[Not an object]");
2351,13 → 2315,13
/**
* Returns an object storing the minimum version required
* of the requested implementations in a piece of source code.
*
*
* @param s : string
* Source code to be analyzed
* @param implementations : Object
* Dictionary of requested implementations. The following
* property names are supported:
*
*
* <table>
* <tr valign="top">
* <th align="left">javascript</th>
2372,7 → 2336,7
* <td>ECMAScript</td>
* </tr>
* <table>
*
*
* @return Object
* An object having the same properties as <var>implementations</var>.
* The property values specify the minimum version required of an
2404,12 → 2368,12
var implMap = {
javascript: "JavaScript",
jscript: "JScript",
es: "ECMAScript Edition",
es: "ECMAScript Edition"
};
 
var result = {};
 
var lines = s.split(/\r?\n|\n/);
var obj = jsx.object;
 
for (var f in features)
{
2426,7 → 2390,10
if (result[i] < features[f][i])
{
result[i] = features[f][i];
console.log(f + " requires " + getattr(implMap, i, i) + " " + features[f][i]);
dmsg(
f + " requires " + obj.getProperty(implMap, i, i)
+ " " + features[f][i],
"warn");
}
}
}