update Ox.doc; add (some) inline comments in Ox.test
This commit is contained in:
parent
250db05abc
commit
f7e58b05e9
1 changed files with 57 additions and 21 deletions
|
@ -20,6 +20,8 @@ Ox.doc <f> Generates documentation for annotated JavaScript
|
||||||
file <s> File name
|
file <s> File name
|
||||||
line <n> Line number
|
line <n> Line number
|
||||||
name <s> Name of the item
|
name <s> Name of the item
|
||||||
|
order <[s]> Order of signature, arguments, properties
|
||||||
|
Present if the type of the item is "function"
|
||||||
properties <[o]|u> Properties (array of doc objects)
|
properties <[o]|u> Properties (array of doc objects)
|
||||||
Present if the <code>type</code> of the item is
|
Present if the <code>type</code> of the item is
|
||||||
<code>"event"</code>, <code>"function"</code>
|
<code>"event"</code>, <code>"function"</code>
|
||||||
|
@ -30,10 +32,10 @@ Ox.doc <f> Generates documentation for annotated JavaScript
|
||||||
line <n> Line
|
line <n> Line
|
||||||
type <s> Type (see Ox.tokenize for a list of types)
|
type <s> Type (see Ox.tokenize for a list of types)
|
||||||
value <s> Value
|
value <s> Value
|
||||||
summary <s> One-line summary
|
returns <[o]> Return values (array of doc objects)
|
||||||
usage <[o]> Usage (array of doc objects)
|
|
||||||
Present if the <code>type</code> of the item is
|
Present if the <code>type</code> of the item is
|
||||||
<code>"function"</code>.
|
<code>"function"</code>.
|
||||||
|
summary <s> One-line summary
|
||||||
tests <[o]> Tests (array of test objects)
|
tests <[o]> Tests (array of test objects)
|
||||||
expected <s> Expected result
|
expected <s> Expected result
|
||||||
statement <s> Statement
|
statement <s> Statement
|
||||||
|
@ -66,9 +68,9 @@ Ox.doc <f> Generates documentation for annotated JavaScript
|
||||||
'Magic constant'
|
'Magic constant'
|
||||||
> Ox.test.doc[1].description
|
> Ox.test.doc[1].description
|
||||||
'Bar per baz is a good indicator of an item\'s foo-ness.'
|
'Bar per baz is a good indicator of an item\'s foo-ness.'
|
||||||
> Ox.test.doc[1].usage[0].types
|
> Ox.test.doc[1].signature[0].types
|
||||||
['number']
|
['number']
|
||||||
> Ox.test.doc[1].usage[0].summary
|
> Ox.test.doc[1].signature[0].summary
|
||||||
'Bar per baz, or NaN'
|
'Bar per baz, or NaN'
|
||||||
> Ox.test.doc[1].tests[1]
|
> Ox.test.doc[1].tests[1]
|
||||||
{expected: 'NaN', statement: 'My.foo({})'}
|
{expected: 'NaN', statement: 'My.foo({})'}
|
||||||
|
@ -78,9 +80,9 @@ Ox.doc = (function() {
|
||||||
item: /^(.+?) <(.+?)> (.+?)$/,
|
item: /^(.+?) <(.+?)> (.+?)$/,
|
||||||
multiline: /^\/\*\@.*?\n([\w\W]+)\n.*?\@?\*\/$/,
|
multiline: /^\/\*\@.*?\n([\w\W]+)\n.*?\@?\*\/$/,
|
||||||
script: /\n(\s*<script>s*\n[\w\W]+\n\s*<\/script>s*)/g,
|
script: /\n(\s*<script>s*\n[\w\W]+\n\s*<\/script>s*)/g,
|
||||||
|
signature: /(\(.*?\)) \->(.*)/,
|
||||||
singleline: /^\/\/@\s*(.*?)\s*$/,
|
singleline: /^\/\/@\s*(.*?)\s*$/,
|
||||||
test: /\n(\s*> .+\n.+?)/g,
|
test: /\n(\s*> .+\n.+?)/g,
|
||||||
usage: /\(.*?\)/
|
|
||||||
},
|
},
|
||||||
types = {
|
types = {
|
||||||
a: 'array', b: 'boolean', d: 'date',
|
a: 'array', b: 'boolean', d: 'date',
|
||||||
|
@ -110,17 +112,21 @@ Ox.doc = (function() {
|
||||||
return matches && (
|
return matches && (
|
||||||
matches[2].indexOf('/') == -1 ||
|
matches[2].indexOf('/') == -1 ||
|
||||||
'\'"'.indexOf(matches[2].slice(-2, -1)) > -1
|
'\'"'.indexOf(matches[2].slice(-2, -1)) > -1
|
||||||
) ? Ox.extend({
|
) ? Ox.extend(
|
||||||
name: parseName(matches[1].trim()),
|
parseName(matches[1]),
|
||||||
summary: matches[3].trim()
|
parseType(matches[2]),
|
||||||
}, parseType(matches[2])) : null;
|
{summary: matches[3].trim()}
|
||||||
|
) : null;
|
||||||
}
|
}
|
||||||
function parseName(string) {
|
function parseName(string) {
|
||||||
var matches = re.usage.exec(string);
|
var matches = re.signature.exec(string);
|
||||||
return matches ? matches[0] : string;
|
return matches
|
||||||
|
? {signature: matches[1], name: matches[2].trim()}
|
||||||
|
: {name: string};
|
||||||
}
|
}
|
||||||
function parseNode(node) {
|
function parseNode(node) {
|
||||||
var item = parseItem(node.line), subitem;
|
var item = parseItem(node.line), order = [];
|
||||||
|
item.name = item.name.replace(/^\./, '');
|
||||||
node.nodes && node.nodes.forEach(function(node) {
|
node.nodes && node.nodes.forEach(function(node) {
|
||||||
var key, line = node.line, subitem;
|
var key, line = node.line, subitem;
|
||||||
if (!/^#/.test(node.line)) {
|
if (!/^#/.test(node.line)) {
|
||||||
|
@ -130,17 +136,21 @@ Ox.doc = (function() {
|
||||||
item.tests = item.tests || [];
|
item.tests = item.tests || [];
|
||||||
item.tests.push(parseTest(line));
|
item.tests.push(parseTest(line));
|
||||||
} else if ((subitem = parseItem(line))) {
|
} else if ((subitem = parseItem(line))) {
|
||||||
if (/^\(/.test(subitem.name)) {
|
if (subitem.signature) {
|
||||||
item.usage = item.usage || [];
|
item.returns = item.returns || [];
|
||||||
item.usage.push(parseNode(node));
|
item.returns.push(parseNode(node));
|
||||||
|
order.push('returns');
|
||||||
} else if (subitem.types[0] == 'event') {
|
} else if (subitem.types[0] == 'event') {
|
||||||
item.events = item.events || [];
|
item.events = item.events || [];
|
||||||
item.events.push(parseNode(node));
|
item.events.push(parseNode(node));
|
||||||
|
order.push('events');
|
||||||
} else {
|
} else {
|
||||||
key = item.types[0] == 'function'
|
key = item.types[0] == 'function'
|
||||||
? 'arguments' : 'properties'
|
&& !/^\./.test(subitem.name)
|
||||||
|
? 'arguments' : 'properties';
|
||||||
item[key] = item[key] || [];
|
item[key] = item[key] || [];
|
||||||
item[key].push(parseNode(node));
|
item[key].push(parseNode(node));
|
||||||
|
order.push(key);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
item.description = item.description
|
item.description = item.description
|
||||||
|
@ -148,6 +158,9 @@ Ox.doc = (function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (item.types[0] == 'function') {
|
||||||
|
item.order = Ox.unique(order);
|
||||||
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
function parseScript(string) {
|
function parseScript(string) {
|
||||||
|
@ -183,6 +196,7 @@ Ox.doc = (function() {
|
||||||
.replace(re.script, encodeLinebreaks)
|
.replace(re.script, encodeLinebreaks)
|
||||||
.replace(re.test, encodeLinebreaks)
|
.replace(re.test, encodeLinebreaks)
|
||||||
.split('\n'),
|
.split('\n'),
|
||||||
|
parent,
|
||||||
tree = parseTree(lines);
|
tree = parseTree(lines);
|
||||||
if (re.item.test(tree.line)) {
|
if (re.item.test(tree.line)) {
|
||||||
// parse the tree's root node
|
// parse the tree's root node
|
||||||
|
@ -200,8 +214,17 @@ Ox.doc = (function() {
|
||||||
} else {
|
} else {
|
||||||
// property of a function item
|
// property of a function item
|
||||||
lastItem = items[items.length - 1];
|
lastItem = items[items.length - 1];
|
||||||
lastItem.properties = lastItem.properties || [];
|
parent = lastItem.types[0] == 'function'
|
||||||
lastItem.properties.push(item);
|
&& lastItem.returns
|
||||||
|
&& lastItem.returns[0].types[0] == 'object'
|
||||||
|
? lastItem.returns[0] : lastItem;
|
||||||
|
parent.properties = parent.properties || [];
|
||||||
|
parent.properties.push(item);
|
||||||
|
if (
|
||||||
|
parent.order && !Ox.contains(parent.order, 'properties')
|
||||||
|
) {
|
||||||
|
parent.order.push('properties');
|
||||||
|
}
|
||||||
// include leading linebreaks and whitespace
|
// include leading linebreaks and whitespace
|
||||||
lastItem.source = lastItem.source.concat(
|
lastItem.source = lastItem.source.concat(
|
||||||
parseTokens(tokens[i], true)
|
parseTokens(tokens[i], true)
|
||||||
|
@ -597,6 +620,7 @@ Ox.test <f> Takes JavaScript, runs inline tests, returns results
|
||||||
section <s|u> Section in the file
|
section <s|u> Section in the file
|
||||||
statement <s> Test statement
|
statement <s> Test statement
|
||||||
passed <b> True if actual result and expected result are equal
|
passed <b> True if actual result and expected result are equal
|
||||||
|
.data <o> undocumented
|
||||||
<script>
|
<script>
|
||||||
Ox.test.foo = function(item) {
|
Ox.test.foo = function(item) {
|
||||||
return item.bar / item.baz;
|
return item.bar / item.baz;
|
||||||
|
@ -620,9 +644,16 @@ Ox.test <f> Takes JavaScript, runs inline tests, returns results
|
||||||
undefined
|
undefined
|
||||||
@*/
|
@*/
|
||||||
Ox.test = function(argument, callback) {
|
Ox.test = function(argument, callback) {
|
||||||
Ox.print('Ox.test', argument, '----------------------------------')
|
// Ansynchronous functions can be tested by calling Ox.test(actual,
|
||||||
|
// expected) in the callback. If Ox.test is called inside a test statement
|
||||||
|
// (unless at the beginning of the statement, which is a test for Ox.test),
|
||||||
|
// the call to Ox.test is patched by inserting the test statement string as
|
||||||
|
// the first argument of the Ox.test call, and Ox.test will branch when
|
||||||
|
// called with three arguments.
|
||||||
function runTests(items) {
|
function runTests(items) {
|
||||||
var id = Ox.uid(), regexp = /(.+Ox\.test\()/, results = [];
|
var id = Ox.uid(), regexp = /(.+Ox\.test\()/, results = [];
|
||||||
|
// We have to create a globally accessible object so that synchronous
|
||||||
|
// and asynchronous tests can read, write and return the same data.
|
||||||
Ox.test.data[id] = {
|
Ox.test.data[id] = {
|
||||||
callback: callback,
|
callback: callback,
|
||||||
done: false,
|
done: false,
|
||||||
|
@ -635,18 +666,20 @@ Ox.test = function(argument, callback) {
|
||||||
}) && item.tests.forEach(function(test) {
|
}) && item.tests.forEach(function(test) {
|
||||||
var actual, isAsync = regexp.test(test.statement);
|
var actual, isAsync = regexp.test(test.statement);
|
||||||
if (isAsync) {
|
if (isAsync) {
|
||||||
|
// Add a pending test
|
||||||
Ox.test.data[id].tests[test.statement] = {
|
Ox.test.data[id].tests[test.statement] = {
|
||||||
name: item.name,
|
name: item.name,
|
||||||
section: item.section
|
section: item.section
|
||||||
};
|
};
|
||||||
Ox.Log('TEST', 'XXX', test.statement);
|
// Patch the test statement
|
||||||
test.statement = test.statement.replace(
|
test.statement = test.statement.replace(
|
||||||
regexp,
|
regexp,
|
||||||
"$1'" + test.statement.replace(/'/g, "\\'") + "', "
|
"$1'" + test.statement.replace(/'/g, "\\'") + "', "
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (test.expected || test.statement.match(/Ox\.test\./)) {
|
if (test.expected || test.statement.match(/Ox\.test\./)) {
|
||||||
// don't eval script tags without assignment to Ox.test.foo
|
// Eval the statement, unless it's a script tag that doesn't
|
||||||
|
// add a property to Ox.test
|
||||||
Ox.Log('TEST', test.statement);
|
Ox.Log('TEST', test.statement);
|
||||||
actual = eval(test.statement);
|
actual = eval(test.statement);
|
||||||
}
|
}
|
||||||
|
@ -671,12 +704,15 @@ Ox.test = function(argument, callback) {
|
||||||
}
|
}
|
||||||
if (arguments.length == 2) {
|
if (arguments.length == 2) {
|
||||||
if (Ox.typeOf(argument) == 'string' && Ox.contains(argument, '\n')) {
|
if (Ox.typeOf(argument) == 'string' && Ox.contains(argument, '\n')) {
|
||||||
|
// source code
|
||||||
runTests(Ox.doc(argument))
|
runTests(Ox.doc(argument))
|
||||||
} else {
|
} else {
|
||||||
argument = Ox.makeArray(argument);
|
argument = Ox.makeArray(argument);
|
||||||
if (Ox.typeOf(argument[0]) == 'string') {
|
if (Ox.typeOf(argument[0]) == 'string') {
|
||||||
|
// files
|
||||||
Ox.doc(argument, runTests);
|
Ox.doc(argument, runTests);
|
||||||
} else {
|
} else {
|
||||||
|
// doc objects
|
||||||
runTests(argument);
|
runTests(argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue