Revised test data

Testing against the output of cook.rb isn't satisfactory because of the
bugs in it; instead we're now going to test against the tiddlywiki.com
build products
This commit is contained in:
Jeremy Ruston
2011-12-03 11:41:25 +00:00
parent db2fafb0ab
commit 07df513140
531 changed files with 34826 additions and 4951 deletions

View File

@@ -0,0 +1,11 @@
This directory contains the test suite for the TiddlyWiki core.
The framework being used is JSSpec (http://jania.pe.kr/aw/moin.cgi/JSSpec).
N.B.:
The use of JSSpec is gradually being phased out in favor of QUnit.
QUnit-based tests are contained in the core/test directory.
cf. http://trac.tiddlywiki.org/ticket/963
/html recipes for building the test suite
/js testing framework
/jsspec actual test code for core modules

View File

@@ -0,0 +1,4 @@
template: test.template.html
style: ../../html/style.txt
recipe: ../../shadows/split.recipe
recipe: ../../js/split.recipe

View File

@@ -0,0 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>
<!--@@title@@-->
</title>
<script id="versionArea" type="text/javascript">
//<![CDATA[
<!--@@version@@-->
//]]>
</script>
<style id="styleArea" type="text/css">
<!--@@style@@-->
</style>
<link rel="stylesheet" type="text/css" href="../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../tools/JSSpec/JSSpec.js"></script>
</head>
<body>
<!--PRE-BODY-START-->
<!--@@prebody@@-->
<!--PRE-BODY-END-->
<div id="saveTest"></div>
<div id="backstageCloak"></div>
<div id="backstageButton"></div>
<div id="backstageArea"><div id="backstageToolbar"></div></div>
<div id="backstage">
<div id="backstagePanel"></div>
</div>
<div id="contentWrapper"></div>
<div id="contentStash"></div>
<div id="shadowArea">
<!--@@shadow@@-->
</div>
<!--POST-SHADOWAREA-->
<div id="storeArea">
<!--@@tiddler@@-->
<!--@@plugin@@-->
<!--@@posttiddlers@@-->
</div>
<!--POST-STOREAREA-->
<!--POST-BODY-START-->
<!--@@postbody@@-->
<!--POST-BODY-END-->
<script id="jsArea" type="text/javascript">
//<![CDATA[
<!--@@prejs@@-->
<!--@@js@@-->
<!--@@postjs@@-->
//]]>
</script>
<!--POST-SCRIPT-START-->
<!--@@postscript@@-->
<!--POST-SCRIPT-END-->
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</body>
</html>

View File

@@ -0,0 +1,23 @@
recipe: test.recipe
title=TiddlyWiki All tests
jsspecsrc=<script type="text/javascript" src="../js/xml.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/xpath.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Animator.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/BasicTypes.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Crypto.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Dates.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Dom.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/FileSystem.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/GenerateRss.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Macros.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Messages.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/RGB.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Shadows.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Strings.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Tiddler.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/TW21Saver.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Version.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Wikifier.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Mocks.jsspec.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/XML.jsspec.js"></script>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>TiddlyWiki tests</title>
<link rel="stylesheet" type="text/css" href="../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../tools/JSSpec/JSSpec.js"></script>
<script type="text/javascript" src="../../js/version.js"></script>
<script type="text/javascript" src="../js/tiddlywiki.js"></script>
<script type="text/javascript" src="../js/mock.js"></script>
<script>
<!--@@jsspec@@-->
</script>
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,4 @@
recipe: test.recipe
title=TiddlyWiki Animator tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Animator.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: test.recipe
title=TiddlyWiki BasicTypes tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/BasicTypes.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
template: testContributors.template.html
style: ../../html/style.txt
recipe: ../../shadows/split.recipe
recipe: ../../js/split.recipe

View File

@@ -0,0 +1,63 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>TiddlyWiki tests</title>
<script id="versionArea" type="text/javascript">
//<![CDATA[
<!--@@version@@-->
//]]>
</script>
<style id="styleArea" type="text/css">
<!--@@style@@-->
</style>
<link rel="stylesheet" type="text/css" href="../../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../../tools/JSSpec/JSSpec.js"></script>
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</head>
<body>
<!--PRE-BODY-START-->
<!--@@prebody@@-->
<!--PRE-BODY-END-->
<div id="saveTest"></div>
<div id="backstageCloak"></div>
<div id="backstageButton"></div>
<div id="backstageArea"><div id="backstageToolbar"></div></div>
<div id="backstage">
<div id="backstagePanel"></div>
</div>
<div id="contentWrapper"></div>
<div id="contentStash"></div>
<div id="shadowArea">
<!--@@shadow@@-->
</div>
<!--POST-SHADOWAREA-->
<div id="storeArea">
<!--@@tiddler@@-->
<!--@@plugin@@-->
<!--@@posttiddlers@@-->
</div>
<!--POST-STOREAREA-->
<!--POST-BODY-START-->
<!--@@postbody@@-->
<!--POST-BODY-END-->
<script id="jsArea" type="text/javascript">
//<![CDATA[
<!--@@prejs@@-->
<!--@@js@@-->
<!--@@postjs@@-->
//]]>
</script>
<!--POST-SCRIPT-START-->
<!--@@postscript@@-->
<!--POST-SCRIPT-END-->
</body>
</html>

View File

@@ -0,0 +1,4 @@
template: testContributors2.template.html
style: ../../html/style.txt
recipe: ../../shadows/split.recipe
recipe: ../../js/split.recipe

View File

@@ -0,0 +1,63 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>TiddlyWiki tests</title>
<script id="versionArea" type="text/javascript">
//<![CDATA[
<!--@@version@@-->
//]]>
</script>
<style id="styleArea" type="text/css">
<!--@@style@@-->
</style>
<link rel="stylesheet" type="text/css" href="../../../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../../../tools/JSSpec/JSSpec.js"></script>
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</head>
<body>
<!--PRE-BODY-START-->
<!--@@prebody@@-->
<!--PRE-BODY-END-->
<div id="saveTest"></div>
<div id="backstageCloak"></div>
<div id="backstageButton"></div>
<div id="backstageArea"><div id="backstageToolbar"></div></div>
<div id="backstage">
<div id="backstagePanel"></div>
</div>
<div id="contentWrapper"></div>
<div id="contentStash"></div>
<div id="shadowArea">
<!--@@shadow@@-->
</div>
<!--POST-SHADOWAREA-->
<div id="storeArea">
<!--@@tiddler@@-->
<!--@@plugin@@-->
<!--@@posttiddlers@@-->
</div>
<!--POST-STOREAREA-->
<!--POST-BODY-START-->
<!--@@postbody@@-->
<!--POST-BODY-END-->
<script id="jsArea" type="text/javascript">
//<![CDATA[
<!--@@prejs@@-->
<!--@@js@@-->
<!--@@postjs@@-->
//]]>
</script>
<!--POST-SCRIPT-START-->
<!--@@postscript@@-->
<!--POST-SCRIPT-END-->
</body>
</html>

View File

@@ -0,0 +1 @@
template: testContributorsMin.template.html

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>
<!--@@title@@-->
</title>
<link rel="stylesheet" type="text/css" href="../../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../../tools/JSSpec/JSSpec.js"></script>
</head>
<body>
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</body>
</html>

View File

@@ -0,0 +1,4 @@
recipe: testmin.recipe
title=TiddlyWiki Crypto tests
jsspecsrc=<script type="text/javascript" src="../../js/Crypto.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Crypto.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: testmin.recipe
title=TiddlyWiki date tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Dates.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: testmin.recipe
title=TiddlyWiki Dom tests
jsspecsrc=<script type="text/javascript" src="../../js/Dom.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Dom.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: testmin.recipe
title=TiddlyWiki FileSystem tests
jsspecsrc=<script type="text/javascript" src="../../js/Config.js"></script>
jsspecsrc=<script type="text/javascript" src="../../js/FileSystem.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/FileSystem.jsspec.js"></script>

View File

@@ -0,0 +1,6 @@
recipe: test.recipe
title=TiddlyWiki GenerateRss tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/xml.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/GenerateRss.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki Macros tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/macros.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: testmin.recipe
title=TiddlyWiki messages tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Messages.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki Mock tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Mocks.jsspec.js"></script>

View File

@@ -0,0 +1,6 @@
recipe: testmin.recipe
title=TiddlyWiki RGB tests
jsspecsrc=<script type="text/javascript" src="../../js/BasicTypes.js"></script>
jsspecsrc=<script type="text/javascript" src="../../js/Strings.js"></script>
jsspecsrc=<script type="text/javascript" src="../../js/RGB.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/RGB.jsspec.js"></script>

View File

@@ -0,0 +1,3 @@
recipe: test.recipe
title=TiddlyWiki Shadow tests
jsspecsrc=<script type="text/javascript" src="../jsspec/Shadows.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: testmin.recipe
title=TiddlyWiki strings tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Strings.jsspec.js"></script>

View File

@@ -0,0 +1,3 @@
recipe: test.recipe
title=TiddlyWiki TWSaver tests
jsspecsrc=<script type="text/javascript" src="../jsspec/TW21Saver.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
template: testTeamTasksPlugins.template.html
style: ../../html/style.txt
recipe: ../../shadows/split.recipe
recipe: ../../js/split.recipe

View File

@@ -0,0 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>TiddlyWiki tests</title>
<script id="versionArea" type="text/javascript">
//<![CDATA[
<!--@@version@@-->
//]]>
</script>
<style id="styleArea" type="text/css">
<!--@@style@@-->
</style>
<link rel="stylesheet" type="text/css" href="../../../../../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../../../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../../../../../tools/JSSpec/JSSpec.js"></script>
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</head>
<body>
<!--PRE-BODY-START-->
<!--@@prebody@@-->
<!--PRE-BODY-END-->
<div id="saveTest"></div>
<div id="backstageCloak"></div>
<div id="backstageButton"></div>
<div id="backstageArea"><div id="backstageToolbar"></div></div>
<div id="backstage">
<div id="backstagePanel"></div>
</div>
<div id="contentWrapper"></div>
<div id="contentStash"></div>
<div id="shadowArea">
<!--@@shadow@@-->
</div>
<!--POST-SHADOWAREA-->
<div id="storeArea">
<!--@@tiddler@@-->
<!--@@plugin@@-->
<!--@@posttiddlers@@-->
</div>
<!--POST-STOREAREA-->
<!--POST-BODY-START-->
<!--@@postbody@@-->
<!--POST-BODY-END-->
<script id="jsArea" type="text/javascript">
//<![CDATA[
<!--@@prejs@@-->
<!--@@js@@-->
<!--@@postjs@@-->
//]]>
</script>
<!--POST-SCRIPT-START-->
<!--@@postscript@@-->
<!--POST-SCRIPT-END-->
</body>
</html>

View File

@@ -0,0 +1,3 @@
recipe: test.recipe
title=TiddlyWiki Tiddler tests
jsspecsrc=<script type="text/javascript" src="../jsspec/Tiddler.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki store tests
jsspecsrc=<script type="text/javascript" src="../../js/TiddlyWiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/TiddlyWiki.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki Utilities tests
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Utilities.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki Version tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Version.jsspec.js"></script>

View File

@@ -0,0 +1,5 @@
recipe: test.recipe
title=TiddlyWiki Wikifier tests
jsspecsrc=<script type="text/javascript" src="../../js/Wikifier.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/mock.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Wikifier.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: test.recipe
title=TiddlyWiki Wizard tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Wizard.jsspec.js"></script>

View File

@@ -0,0 +1,6 @@
recipe: test.recipe
title=TiddlyWiki XML tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/xml.js"></script>
jsspecsrc=<script type="text/javascript" src="../js/xpath.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/XML.jsspec.js"></script>

View File

@@ -0,0 +1,4 @@
recipe: test.recipe
title=TiddlyWiki Zoomer tests
jsspecsrc=<script type="text/javascript" src="../js/tiddlywiki.js"></script>
jsspecsrc=<script type="text/javascript" src="../jsspec/Zoomer.jsspec.js"></script>

View File

@@ -0,0 +1 @@
template: testmin.template.html

View File

@@ -0,0 +1,21 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>
<!--@@title@@-->
</title>
<link rel="stylesheet" type="text/css" href="../../../tools/JSSpec/JSSpec.css" />
<script type="text/javascript" src="../../../tools/JSSpec/diff_match_patch.js"></script>
<script type="text/javascript" src="../../../tools/JSSpec/JSSpec.js"></script>
<script type="text/javascript">
<!--@@jsspec@@-->
</script>
<!--@@jsspecsrc@@-->
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,7 @@
#!/bin/bash
TWDIR=$HOME/Documents/TiddlyWiki
DEFAULT_FILENAME=tiddlywiki
FILENAME=${1:-$DEFAULT_FILENAME}
DEST=$PWD
RECIPE=$PWD/$FILENAME.js.recipe
ruby -C ../../../tools/cooker cook.rb $RECIPE -d$DEST -s $2 $3 $4 $5

View File

@@ -0,0 +1,65 @@
tests_mock = {
frame: {},
/*
* replace named global functions with a mock version
* - mock can access original function, and store context in tests_mock.frame[funcName]
*/
before: function(funcName,mocker)
{
var frame = {};
frame.called = 0;
frame.savedFunc = eval(funcName);
if (typeof frame.savedFunc != "function")
throw(funcName +" is not a function: " + (typeof frame.savedFunc));
var mockFunction = function() {
tests_mock.frame[funcName].called++;
if (mocker)
return mocker.apply(this, arguments);
};
eval(funcName + "=mockFunction");
this.frame[funcName] = frame;
},
/*
* restore named global function
* - return frame object, which includes a count of calls
*/
after: function(funcName)
{
frame = this.frame[funcName];
eval(funcName + '=frame.savedFunc');
return frame;
},
/*
* save values of named global variables
*/
save: function(varName)
{
var frame = {};
frame.restore = true;
frame.savedValue = eval(varName);
if (typeof frame.savedValue == "function")
throw(varName +" is a function: " + (typeof frame.savedValue));
this.frame[varName] = frame;
},
/*
* restore any named global variables
*/
restore: function()
{
var varName;
for(varName in this.frame) {
frame = this.frame[varName];
if (frame.restore){
eval(varName+'=frame.savedValue');
frame.restore = false;
}
}
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
template: tiddlywiki.template.js
recipe: ../../js/split.recipe

View File

@@ -0,0 +1,5 @@
//<![CDATA[
<!--@@prejs@@-->
<!--@@js@@-->
<!--@@postjs@@-->
//]]>

View File

@@ -0,0 +1,36 @@
tests_xml = {
parse: function(text) {
var doc;
if(window.ActiveXObject) {
doc = new ActiveXObject("Microsoft.XMLDOM");
doc.async = "false";
doc.loadXML(text);
} else {
var parser = new DOMParser();
doc = parser.parseFromString(text,"text/xml");
}
if(!doc) {
return null;
}
doc.xpath = function(expression, type) {
var t;
if(type == "string") { t = XPathResult.STRING_TYPE; }
if(type == "number") { t = XPathResult.NUMBER_TYPE; }
if(type == "boolean") { t = XPathResult.BOOLEAN_TYPE; }
if(type == "singlenode") { t = XPathResult.SINGLENODE_TYPE; }
var res = this.evaluate(expression, this, null, t, null);
if(type == "string") { return res.stringValue; }
if(type == "number") { return res.numberValue; }
if(type == "boolean") { return res.booleanValue; }
if(type == "singleNode") { return this.singleNodeValue; }
return null;
};
return doc;
}
};

View File

@@ -0,0 +1,626 @@
/*
javascript-xpath, an implementation of DOM Level 3 XPath for Internet Explorer 5+
Copyright (C) 2004 Dimitri Glazkov Modified 2006 Mehdi Hassan
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
*/
// Mozilla, Firefox, Safari etc have support by default, we don't have an implementation for the rest
if (!(XPathResult.NUMBER_TYPE + XPathResult.NUMBER_TYPE))
{
window._content = window;
var _tb_windowEvents = new Array();
window.addEventListener = function(event, handler, flag) {
_tb_windowEvents[event] = handler;
};
function _tb_postProcess() {
if (_tb_windowEvents["load"]) {
_tb_windowEvents["load"]();
}
}
var extern;
if (window.dialogArguments && window.dialogArguments.external) {
extern = window.dialogArguments.external;
} else if (window.external) {
extern = window.external;
}
// XPathException
// An Error object will be thrown, this is just a handler to instantiate that object
var XPathException = new _XPathExceptionHandler();
function _XPathExceptionHandler()
{
this.INVALID_EXPRESSION_ERR = 51;
this.TYPE_ERR = 52;
this.NOT_IMPLEMENTED_ERR = -1;
this.RUNTIME_ERR = -2;
this.ThrowNotImplemented = function(message)
{
ThrowError(this.NOT_IMPLEMENTED_ERR, "This functionality is not implemented.", message);
};
this.ThrowInvalidExpression = function(message)
{
ThrowError(this.INVALID_EXPRESSION_ERR, "Invalid expression", message);
};
this.ThrowType = function(message)
{
ThrowError(this.TYPE_ERR, "Type error", message);
};
this.Throw = function(message)
{
ThrowError(this.RUNTIME_ERR, "Run-time error", message);
};
function ThrowError(code, description, message)
{
var error = new Error(code, "DOM-L3-XPath : " + description + (message ? ", \"" + message + "\"": ""));
error.code = code;
error.name = "XPathException";
throw error;
}
}
// DOMException
// An Error object will be thrown, this is just a handler to instantiate that object
var DOMException = new _DOMExceptionHandler();
function _DOMExceptionHandler()
{
this.ThrowInvalidState = function(message)
{
ThrowError(13, "The state of the object is no longer valid", message);
};
function ThrowError(code, description, message)
{
var error = new Error(code, "DOM : " + description + (message ? ", \"" + message + "\"": ""));
error.code = code;
error.name = "DOMException";
throw error;
}
}
// XPathEvaluator
// implemented as document object methods
// XPathExpression createExpression(String expression, XPathNSResolver resolver)
document.createExpression = function
(
expression, // String
resolver // XPathNSResolver
)
{
// returns XPathExpression object
return new XPathExpression(expression, resolver);
};
// XPathNSResolver createNSResolver(nodeResolver)
document.createNSResolver = function
(
nodeResolver // Node
)
{
// returns XPathNSResolver
return new XPathNSResolver(nodeResolver);
};
// XPathResult evaluate(String expresison, Node contextNode, XPathNSResolver resolver, Number type, XPathResult result)
document.evaluate = function
(
expression, // String
contextNode, // Node
resolver, // XPathNSResolver
type, // Number
result // XPathResult
)
// can raise XPathException, DOMException
{
// return XPathResult
return document.createExpression(expression, resolver).evaluate(contextNode, type, result);
};
// XPathExpression
function XPathExpression
(
expression, // String
resolver // XPathNSResolver
)
{
this.expressionString = expression;
this.resolver = resolver;
// XPathResult evaluate(Node contextNode, Number type, XPathResult result)
this.evaluate = function
(
contextNode, // Node
type, // Number
result // XPathResult
)
// raises XPathException, DOMException
{
// return XPathResult
return (result && result.constructor == XPathResult ? result.initialize(this, contextNode, resolver, type) : new XPathResult(this, contextNode, resolver, type));
};
this.toString = function()
{
return "[XPathExpression]";
};
}
// XPathNSResolver
function XPathNSResolver(node)
{
this.node = node;
// String lookupNamespaceURI(String prefix)
this.lookupNamespaceURI = function
(
prefix // String
)
{
XPathException.ThrowNotImplemented();
// return String
return null;
};
this.toString = function()
{
return "[XPathNSResolver]";
};
}
// XPathResult
XPathResult.ANY_TYPE = 0;
XPathResult.NUMBER_TYPE = 1;
XPathResult.STRING_TYPE = 2;
XPathResult.BOOLEAN_TYPE = 3;
XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4;
XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5;
XPathResult.UNORDERED_SNAPSHOT_TYPE = 6;
XPathResult.ORDERED_SNAPSHOT_TYPE = 7;
XPathResult.ANY_UNORDERED_NODE_TYPE = 8;
XPathResult.FIRST_ORDERED_NODE_TYPE = 9;
function XPathResult
(
expression, // XPathExpression
contextNode, // Node
resolver, // XPathNSResolver
type // Number
)
{
this.initialize = function(expression, contextNode, resolver, type)
{
this._domResult = null;
this._expression = expression;
this._contextNode = contextNode;
this._resolver = resolver;
if (type)
{
this.resultType = type;
this._isIterator = (type == XPathResult.UNORDERED_NODE_ITERATOR_TYPE ||
type == XPathResult.ORDERED_NODE_ITERATOR_TYPE ||
type == XPathResult.ANY_TYPE);
this._isSnapshot = (type == XPathResult.UNORDERED_SNAPSHOT_TYPE || type == XPathResult.ORDERED_SNAPSHOT_TYPE);
this._isNodeSet = type > XPathResult.BOOLEAN_TYPE;
}
else
{
this.resultType = XPathResult.ANY_TYPE;
this._isIterator = true;
this._isSnapshot = false;
this._isNodeSet = true;
}
return this;
};
this.initialize(expression, contextNode, resolver, type);
this.getInvalidIteratorState = function()
{
return documentChangeDetected() || !this._isIterator;
};
this.getSnapshotLength = function()
// raises XPathException
{
if (!this._isSnapshot)
{
XPathException.ThrowType("Snapshot is not an expected result type");
}
activateResult(this);
// return Number
return this._domResult.length;
};
// Node iterateNext()
this.iterateNext = function()
// raises XPathException, DOMException
{
if (!this._isIterator)
{
XPathException.ThrowType("Iterator is not an expected result type");
}
activateResult(this);
if (documentChangeDetected())
{
DOMException.ThrowInvalidState("iterateNext");
}
// return Node
return getNextNode(this);
};
// Node snapshotItem(Number index)
this.snapshotItem = function(index)
// raises XPathException
{
if (!this._isSnapshot)
{
XPathException.ThrowType("Snapshot is not an expected result type");
}
// return Node
return getItemNode(this, index);
};
this.toString = function()
{
return "[XPathResult]";
};
// returns string value of the result, if result type is STRING_TYPE
// otherwise throws an XPathException
this.getStringValue = function()
{
if (this.resultType != XPathResult.STRING_TYPE)
{
XPathException.ThrowType("The expression can not be converted to return String");
}
return getNodeText(this);
};
// returns number value of the result, if the result is NUMBER_TYPE
// otherwise throws an XPathException
this.getNumberValue = function()
{
if (this.resultType != XPathResult.NUMBER_TYPE)
{
XPathException.ThrowType("The expression can not be converted to return Number");
}
var number = parseInt(getNodeText(this));
if (isNaN(number))
{
XPathException.ThrowType("The result can not be converted to Number");
}
return number;
};
// returns boolean value of the result, if the result is BOOLEAN_TYPE
// otherwise throws an XPathException
this.getBooleanValue = function()
{
if (this.resultType != XPathResult.BOOLEAN_TYPE)
{
XPathException.ThrowType("The expression can not be converted to return Boolean");
}
var
text = getNodeText(this);
bool = (text ? text.toLowerCase() : null);
if (bool == "false" || bool == "true")
{
return bool;
}
XPathException.ThrowType("The result can not be converted to Boolean");
};
// returns single node, if the result is ANY_UNORDERED_NODE_TYPE or FIRST_ORDERED_NODE_TYPE
// otherwise throws an XPathException
this.getSingleNodeValue = function()
{
if (this.resultType != XPathResult.ANY_UNORDERED_NODE_TYPE &&
this.resultType != XPathResult.FIRST_ORDERED_NODE_TYPE)
{
XPathException.ThrowType("The expression can not be converted to return single Node value");
}
return getSingleNode(this);
};
function documentChangeDetected()
{
return document._XPathMsxmlDocumentHelper.documentChangeDetected();
}
function getNodeText(result)
{
activateResult(result);
return result._textResult;
// return ((node = getSingleNode(result)) ? (node.nodeType == 1 ? node.innerText : node.nodeValue) : null);
}
function findNode(result, current)
{
switch(current.nodeType)
{
case 1: // NODE_ELEMENT
var id = current.attributes.getNamedItem("id");
if (id)
{
return document.getElementById(id.value);
}
XPathException.Throw("unable to locate element in XML tree");
case 2: // NODE_ATTRIBUTE
var id = current.selectSingleNode("..").attributes.getNamedItem("id");
if (id)
{
var node = document.getElementById(id.text);
if (node)
{
return node.attributes.getNamedItem(current.nodeName);
}
}
XPathException.Throw("unable to locate attribute in XML tree");
case 3: // NODE_TEXT
var id = current.selectSingleNode("..").attributes.getNamedItem("id");
if (id)
{
var node = document.getElementById(id.value);
if (node)
{
for(child in node.childNodes)
{
if (child.nodeType == 3 && child.nodeValue == current.nodeValue)
{
return child;
}
}
}
}
XPathException.Throw("unable to locate text in XML tree");
}
XPathException.Throw("unknown node type");
}
function activateResult(result)
{
if (!result._domResult)
{
try
{
var expression = result._expression.expressionString;
// adjust expression if contextNode is not a document
if (result._contextNode != document && expression.indexOf("//") != 0)
{
expression = "//*[@id = '" + result._contextNode.id + "']" +
(expression.indexOf("/") == 0 ? "" : "/") + expression;
}
if (result._isNodeSet)
{
result._domResult = document._XPathMsxmlDocumentHelper.getDom().selectNodes(expression);
}
else
{
result._domResult = true;
result._textResult = document._XPathMsxmlDocumentHelper.getTextResult(expression);
}
}
catch(error)
{
alert(error.description);
XPathException.ThrowInvalidExpression(error.description);
}
}
}
function getSingleNode(result)
{
var node = getItemNode(result, 0);
result._domResult = null;
return node;
}
function getItemNode(result, index)
{
activateResult(result);
var current = result._domResult.item(index);
return (current ? findNode(result, current) : null);
}
function getNextNode(result)
{
var current = result._domResult.nextNode;
if (current)
{
return findNode(result, current);
}
result._domResult = null;
return null;
}
}
document.reloadDom = function()
{
document._XPathMsxmlDocumentHelper.reset();
};
document._XPathMsxmlDocumentHelper = new _XPathMsxmlDocumentHelper();
function _XPathMsxmlDocumentHelper()
{
this.getDom = function()
{
activateDom(this);
return this.dom;
};
this.getXml = function()
{
activateDom(this);
return this.dom.xml;
};
this.getTextResult = function(expression)
{
expression = expression.replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "\"");
var xslText = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" +
"<xsl:output method=\"text\"/><xsl:template match=\"*\"><xsl:value-of select=\"" + expression + "\"/>" +
"</xsl:template></xsl:stylesheet>";
var xsl = new ActiveXObject("Msxml2.DOMDocument");
xsl.loadXML(xslText);
try
{
var result = this.getDom().transformNode(xsl);
}
catch(error)
{
alert("Error: " + error.description);
}
return result;
};
this.reset = function()
{
this.dom = null;
};
function onPropertyChangeEventHandler()
{
document._propertyChangeDetected = true;
};
this.documentChangeDetected = function()
{
return (document.ignoreDocumentChanges ? false : this._currentElementCount != document.all.length || document._propertyChangeDetected);
};
function activateDom(helper)
{
if (!helper.dom)
{
var dom = new ActiveXObject("Msxml2.DOMDocument");
dom.async = false;
dom.resolveExternals = false;
loadDocument(dom, helper);
helper.dom = dom;
helper._currentElementCount = document.all.length;
document._propertyChangeDetected = false;
}
else
{
if (helper.documentChangeDetected())
{
var dom = helper.dom;
dom.load("");
loadDocument(dom, helper);
helper._currentElementCount = document.all.length;
document._propertyChangeDetected = false;
}
}
}
function loadDocument(dom, helper)
{
return loadNode(dom, dom, document.body, helper);
}
function loadNode(dom, domParentNode, node, helper)
{
if (node.nodeType == 3)
{
domParentNode.appendChild(dom.createTextNode(node.nodeValue));
}
else
{
var domNode = dom.createElement(node.nodeName.toLowerCase());
if (!node.id)
{
node.id = node.uniqueID;
}
domParentNode.appendChild(domNode);
loadAttributes(dom, domNode, node);
var length = node.childNodes.length;
for(var i = 0; i < length; i ++ )
{
loadNode(dom, domNode, node.childNodes[i], helper);
}
node.attachEvent("onpropertychange", onPropertyChangeEventHandler);
}
}
function loadAttributes(dom, domParentNode, node)
{
for (var i = 0; i < node.attributes.length; i ++ )
{
var attribute = node.attributes[i];
var attributeValue = attribute.nodeValue;
if (attributeValue && attribute.specified)
{
var domAttribute = dom.createAttribute(attribute.nodeName);
domAttribute.value = attributeValue;
domParentNode.setAttributeNode(domAttribute);
}
}
}
}
}
else
{
document.reloadDom = function() {};
XPathResult.prototype.getStringValue = function()
{
return this.stringValue;
};
XPathResult.prototype.getNumberValue = function()
{
return this.numberValue;
};
XPathResult.prototype.getBooleanValue = function()
{
return this.booleanValue;
};
XPathResult.prototype.getSingleNodeValue = function()
{
return this.singleNodeValue;
};
XPathResult.prototype.getInvalidIteratorState = function()
{
return this.invalidIteratorState;
};
XPathResult.prototype.getSnapshotLength = function()
{
return this.snapshotLength;
};
XPathResult.prototype.getResultType = function()
{
return this.resultType;
};
}

View File

@@ -0,0 +1,287 @@
// <![CDATA[
/* migrated to QUnit */
describe('BasicTypes : Number.clamp()', {
before_each: function(){
max = 10;
min = 5;
},
'given a number below the minium value, Number.clamp() brings the number into the range' : function() {
var n = 2;
n = n.clamp(min,max);
value_of(n).should_be(min);
},
'given a number above the maximum value, Number.clamp() brings the number into the range' : function() {
var n = 20;
n = n.clamp(min,max);
value_of(n).should_be(max);
},
'given a number within the perscribed range, Number.clamp() returns the original value' : function() {
var n = 7;
n = n.clamp(min,max);
value_of(n).should_be(7);
}
});
describe('BasicTypes : Array.indexOf()', {
before_each: function(){
test_arr = ['item1', 'item2','item3'];
},
'an array object should have an indexOf method.' : function() {
var t = typeof test_arr.indexOf;
value_of(t).should_be('function');
},
'given the value of the element at position 0, indexOf should return 0' : function() {
value_of(test_arr.indexOf('item1')).should_be(0);
},
'given a value not present in an array, indexOf should return -1' : function() {
value_of(test_arr.indexOf('noitem')).should_be(-1);
},
'indexOf should retuen the index of an element in a restricted range in an array' : function() {
value_of(test_arr.indexOf('item3',1)).should_be(2);
},
'indexOf should return -1 when searching for an element outside a restricted range in an array' : function() {
value_of(test_arr.indexOf('item1',1)).should_be(-1);
}
});
describe('BasicTypes : Array.contains()', {
before_each: function(){
test_arr = ['item1', 'item2','item3'];
},
'given an item which exist in the array, contains() will return true' : function() {
var res = test_arr.contains('item1');
value_of(res).should_be_true();
},
'given an item which does not exist in the array, contains() will return false' : function() {
var res = test_arr.contains('dud');
value_of(res).should_be_false();
}
});
describe('BasicTypes : Array.setItem()', {
before_each: function(){
test_arr = ['item1', 'item2','item3'];
},
'given a string and a mode value of +1, setItem() will add the string to an array. ' : function() {
test_arr.setItem('item4',+1);
value_of(test_arr.length).should_be(4);
},
'given a string which is present in the array and a mode value of -1, setItem() will remove the string from an array. ' : function() {
test_arr.setItem('item3',-1);
value_of(test_arr.length).should_be(2);
},
'given a string which is not present in the array and a mode value of -1, setItem() will not modify the array. ' : function() {
test_arr.setItem('item4',-1);
value_of(test_arr.length).should_be(3);
},
'given a string which is present in the array and a mode value of 0, setItem() will remove the string from the array. ' : function() {
test_arr.setItem('item2', 0);
value_of(test_arr.length).should_be(2);
},
'given a string which is not present in the array and a mode value of 0, setItem() will add the string to the array. ' : function() {
test_arr.setItem('item4', 0);
value_of(test_arr.length).should_be(4);
}
});
describe('BasicTypes : Array.containsAny()', {
before_each: function(){
test_strings_arr = ['item1', 'item2','item3'];
},
'given a test array containing on string which is present in the array, containsAny() returns true.' : function() {
var result = test_strings_arr.containsAny(['item1']);
value_of(result).should_be_true();
},
'given a test array containing 2 strings which are present in the array, containsAny() returns true.' : function() {
var result = test_strings_arr.containsAny(['item1','item3']);
value_of(result).should_be_true();
},
'given a test array containing a string which is not present in the array, containsAny() returns false.' : function() {
var result = test_strings_arr.containsAny(['item4']);
value_of(result).should_be_false();
},
'given a test array containing one string which is present and one which is not present in the array, containsAny() returns true.' : function() {
var result = test_strings_arr.containsAny(['item1','item4']);
value_of(result).should_be_true();
}
});
describe('BasicTypes : Array.containsAll()', {
before_each: function(){
test_strings_arr = ['item1','item2','item3'];
},
'given a list of string items, none of which are present in the target array, containsAll() returns false.' : function() {
var query_arr = ['itemA','itemB'];
var result = test_strings_arr.containsAll(query_arr);
value_of(result).should_be_false();
},
'given a list of string items, some of which are present in the target array, containsAll() returns false.' : function() {
var query_arr = ['item1','itemB'];
var result = test_strings_arr.containsAll(query_arr);
value_of(result).should_be_false();
},
'given a list of string items, all of which are present in the target array, containsAll() returns true.' : function() {
var query_arr = ['item1','item2'];
var result = test_strings_arr.containsAll(query_arr);
value_of(result).should_be_true();
}
});
describe('BasicTypes : Array.pushUnique()', {
before_each: function(){
test_strings_arr = ['item1','item2','item3'];
},
'given a string value which is not present in the target array, pushUnique() adds the value to the array' : function() {
var originalLength = test_strings_arr.length;
test_strings_arr.pushUnique('item4');
var modifiedLength = test_strings_arr.length;
value_of(modifiedLength).should_be(originalLength+1);
},
'given a string value which is already present in the target array, pushUnique() does not change the target array.' : function() {
var originalLength = test_strings_arr.length;
test_strings_arr.pushUnique('item2');
var modifiedLength = test_strings_arr.length;
value_of(modifiedLength).should_be(originalLength);
},
'given a string value which is already present in the target array and a value of false in the unique parameter, pushUnique() add the item to the target array.' : function() {
var originalLength = test_strings_arr.length;
test_strings_arr.pushUnique('item2',false);
var modifiedLength = test_strings_arr.length;
value_of(modifiedLength).should_be(originalLength + 1);
},
// Tests pending object handling in pushUnique. (http://trac.tiddlywiki.org/ticket/606)
'given an object which is not already present in the target array, pushUnique() will add the object to the array' : function() {
var test_obj_arr = [{id: 1}, {id: 2 }];
test_obj_arr.pushUnique({id:3});
value_of(test_obj_arr.length).should_be(3);
},
'given an object which is already present in the target array, pushUnique() will not add the object to the array' : function() {
var test_obj_arr = [{id: 1}, {id: 2 }];
// test_obj_arr.pushUnique({id:2});
value_of(test_obj_arr.length).should_be(2);
}
});
describe('BasicTypes : Array.remove()', {
before_each: function() {
test_strings_arr = ['item1', 'item2', 'item3'];
},
'given a string which is present as an item in the array, Array.remove() will remove the item from the array.' : function() {
test_strings_arr.remove('item1');
var ispresent = test_strings_arr.indexOf('item1');
value_of(ispresent).should_be(-1);
},
'given a string which is not present as an item in the array, Array.remove() takes no action and throws no errors.' : function() {
test_strings_arr.remove('itemA');
value_of(test_strings_arr.length).should_be(3);
}
// 'given an object which is present in the array, Array.remove() removes the object from the array.' : function() {
// test_obj_arr = [{id: 1}, {id: 2 }];
// test_obj_arr.remove({id: 1 });
// value_of(test_obj_arr.length).should_be(1);
// }
});
describe('BasicTypes : Array.map()', {
'mapping a function onto an array will allow that function to be called on any item in the array ' : function() {
var numbers = [0,1,2,3,4,5];
var fn = function(n) { return n*n; };
var squared = numbers.map(fn);
var three_squared = squared[3];
value_of(three_squared).should_be(9);
}
});
// Tests pending object comparison for use in functions like pushUnique. (http://trac.tiddlywiki.org/ticket/606)
describe('BasicTypes : objectsMatch()', {
// 'given two identical objects, Object.match() returns true' : function() {
// var obj1 = {name: "obj1", value: "a value"};
// var obj2 = {name: "obj1", value: "a value"};
// var result = objectsMatch(obj1,obj2);
// value_of(result).should_be_true();
// },
//
// 'given two different objects, Object.match() returns false' : function() {
// var obj1 = {name: "obj1", value: "a value"};
// var obj2 = {name: "obj2", value: "a value"};
// var result = objectsMatch(obj1,obj2);
// value_of(result).should_be_false();
// },
//
// 'given two identical objects, which each contain objects, Object.match() returns true' : function() {
// var obj1a = {name: "foo", value: "bar"};
// var obj1 = {name: "foo", value: obj1a};
// var obj2 = {name: "foo", value: obj1a};
// var result = objectsMatch(obj1,obj2);
// value_of(result).should_be_true();
// }
// 'given two objects, which each contain different objects, Object.match() returns false' : function() {
// var obj1a = {name: "foo", value: "bar"};
// var obj2a = {name: "bub", value: "baz"};
// var obj1 = {name: "foo", value: obj1a};
// var obj2 = {name: "foo", value: obj2a};
// var result = objectsMatch(obj1,obj2);
// value_of(result).should_be_false();
// }
});
// ]]>

View File

@@ -0,0 +1,221 @@
// <![CDATA[
function __main()
{
store = new TiddlyWiki();
loadShadowTiddlers();
formatter = new Formatter(config.formatters);
story = new Story("tiddlerDisplay","tiddler");
}
__title = {
en: {
all: "All tiddlers in alphabetical order",
missing: "Tiddlers that have links to them but are not defined",
orphans: "Tiddlers that are not linked to from any other tiddlers",
shadowed: "Tiddlers shadowed with default contents",
touched: "Tiddlers that have been modified locally",
closeAll: "Close all displayed tiddlers (except any that are being edited)",
permaview: "Link to an URL that retrieves all the currently displayed tiddlers",
saveChanges: "Save all tiddlers to create a new TiddlyWiki",
tagChooser: "Choose existing tags to add to this tiddler",
refreshDisplay: "Redraw the entire TiddlyWiki display"
}
}
function __re_escape(s)
{
s = "" + s;
return s.replace('(','\\(').replace(')','\\)');
}
function testing_check_button(name,text,accesskey)
{
var t = wikifyStatic("<<"+name+">>");
var title = __re_escape(__title.en[name]);
var r = new RegExp('<a(( accesskey="'+accesskey+'")|( class="button")|( title="' + title + '")|( href="javascript:;")){3,4}>'+text+'<\/a>$');
value_of(t).should_match(r);
value_of(t).should_match(/class="/);
value_of(t).should_match(/title="/);
value_of(t).should_match(/href="/);
if (accesskey)
value_of(t).should_match(/accesskey="/);
}
function testing_check_button_onclick(name,func)
{
tests_mock.before(func);
config.macros[name].onClick();
value_of(tests_mock.after(func).called).should_be(1);
}
describe('Macros: macro errors', {
before_each : function() {
__main();
},
'missing macro should produce errortext' : function() {
value_of(wikifyStatic('<<NOEXISTANTMACRO>>')).should_match(/errortext/);
}
});
describe('Macros: version macro', {
before_each : function() {
__main();
},
'version macro should expand to the version string' : function() {
version.major = "123";
version.minor = "456";
version.revision = "789";
version.beta = "123456789";
value_of(wikifyStatic("<<version>>")).should_match(/^<(span|SPAN)>123.456.789 \(beta 123456789\)<\/(span|SPAN)>$/);
}
});
describe('Macros: today macro', {
before_each : function() {
__main();
},
'today macro should return a date-shaped string [known to fail]' : function() {
value_of(wikifyStatic("<<today>>")).should_match(/^<(span|SPAN)>[A-Z][a-z]+\s[A-Z][a-z]+\s+[0-9]{1,2}\s[0-9]{2}:[0-9]{2}:[0-9]{2} 2[0-9]{3}<\/(span|SPAN)>$/);
}
});
describe('Macros: list macro', {
before_each : function() {
__main();
},
'list all by default expands to the listTitle and an empty list' : function() {
value_of(wikifyStatic("<<list>>")).should_be('<ul><li class="listTitle">' + __title.en.all + '</li></ul>');
},
'list missing by default expands to the listTitle and an empty list' : function() {
value_of(wikifyStatic("<<list missing>>")).should_be('<ul><li class="listTitle">' + __title.en.missing + '</li></ul>');
},
'list orphans by default expands to the listTitle and an empty list' : function() {
value_of(wikifyStatic("<<list orphans>>")).should_be('<ul><li class="listTitle">' + __title.en.orphans + '</li></ul>');
},
'list shadowed by default expands to the listTitle and a list of tiddlers' : function() {
var pattern = new RegExp('^<ul><li class="listTitle">' + __title.en.shadowed + '</li><li>.*<\/li><\/ul>');
value_of(wikifyStatic("<<list shadowed>>")).should_match(pattern);
},
'list touched by default expands to the listTitle and empty list' : function() {
value_of(wikifyStatic("<<list touched>>")).should_be('<ul><li class="listTitle">' + __title.en.touched + '</li></ul>');
},
'list filter by default expands to an empty list' : function() {
value_of(wikifyStatic("<<list filter>>")).should_be('<ul></ul>');
}
});
describe('Macros: closeAll macro', {
before_each : function() {
__main();
},
'closeAll macro expands to button' : function() {
testing_check_button("closeAll","close all");
},
'closeAll.onClick calls the story.closeAllTiddlers function' : function() {
testing_check_button_onclick("closeAll","story.closeAllTiddlers");
}
});
describe('Macros: permaview macro', {
before_each : function() {
__main();
},
'permaview macro expands to button' : function() {
testing_check_button("permaview","permaview");
},
'permaview.onClick calls the story.permaView function' : function() {
testing_check_button_onclick("permaview","story.permaView");
}
});
describe('Macros: saveChanges macro', {
before_each : function() {
__main();
},
'saveChanges macro doesn\'t expand to button when readOnly' : function() {
readOnly = true;
value_of(wikifyStatic("<<saveChanges>>")).should_be("");
},
'saveChanges macro expands to button when not readOnly' : function() {
readOnly = false;
testing_check_button("saveChanges","save changes","S");
},
'saveChanges.onClick calls the saveChanges function' : function() {
testing_check_button_onclick("saveChanges","saveChanges");
}
});
describe('Macros: message macro', {
before_each : function() {
__main();
tests_mock.save('config.options.txtUserName');
},
after_each : function() {
tests_mock.restore();
},
'message with no parameters returns an empty string' : function() {
value_of(wikifyStatic("<<message>>")).should_be('');
},
'message with returns an empty string' : function() {
var username = "MyAssertedUserName";
config.options.txtUserName = username;
value_of(wikifyStatic("<<message config.options.txtUserName>>")).should_be(username);
},
});
describe('Macros: tagChooser macro', {
before_each : function() {
__main();
tests_mock.save('config.options.txtUserName');
},
after_each : function() {
tests_mock.restore();
},
'tagChooser with no parameters returns an empty string' : function() {
var t = wikifyStatic("<<tagChooser>>");
var title = __title.en.tagChooser;
var text = "tags";
var r = new RegExp('<a(( tiddler="temp")|( class="button")|( title="' + title + '")|( href="javascript:;")){4,4}>'+text+'<\/a>$');
value_of(t).should_match(r);
value_of(t).should_match(/tiddler="/);
value_of(t).should_match(/class="/);
value_of(t).should_match(/title="/);
value_of(t).should_match(/href="/);
}
});
describe('Macros: refreshDisplay macro', {
before_each : function() {
__main();
},
'refreshDisplay macro expands to button' : function() {
testing_check_button("refreshDisplay","refresh");
},
'refreshDisplay.onClick calls the refreshAll function' : function() {
testing_check_button_onclick("refreshDisplay","refreshAll");
}
});
describe('Macros: annotations macro', {
before_each : function() {
store = new TiddlyWiki();
loadShadowTiddlers();
store.saveTiddler("t","t","text");
formatter = new Formatter(config.formatters);
},
'annotations macro for a non-tiddler expands the empty string' : function() {
value_of(wikifyStatic("<<annotations>>")).should_be('');
},
'annotations macro expands to empty string for tiddler not in config.annotations' : function() {
value_of(wikifyStatic("<<annotations>>",null,new Tiddler("temp"))).should_be('');
},
'annotations macro expands to config.annotations defined text' : function() {
var title = "This is the title text";
config.annotations.temp = title;
value_of(wikifyStatic("<<annotations>>",null,new Tiddler("temp"))).should_be('<div class="annotation">'+title+'</div>');
}
});
// ]]>

View File

@@ -0,0 +1,39 @@
// <![CDATA[
function getMessage() {
return msgArea.getElementsByTagName("div")[1].innerHTML;
}
describe('displayMessage',
{
before_each: function() {
msgArea = createTiddlyElement(document.body,"div","messageArea");
msgArea.style.visibility = "hidden"; },
after_each: function() {
removeNode(msgArea);
},
'should raise an alert if the messageArea element does not exist': function() {
msgArea.id = "messageArea_disabled";
var text = "alert this text!";
tests_mock.before('alert', function() {
tests_mock.frame['alert'].args = arguments;
});
displayMessage(text);
frame = tests_mock.after('alert');
value_of(frame.called).should_be(1);
value_of(frame.args[0]).should_be(text);
},
'should put single letter "s" into the message area': function() {
var text = "s";
displayMessage(text);
var actual = getMessage();
value_of(actual).should_be(text);
},
'should put text into the message area': function() {
var text = "The quick brown fox jumps over the lazy dog";
displayMessage(text);
var actual = getMessage();
value_of(actual).should_be(text);
}
});
// ]]>

View File

@@ -0,0 +1,82 @@
// <![CDATA[
describe('Mock: testing framework mock functions', {
before_each : function() {
mock_me = function() {
return "ha-ha!";
}
mock_me2 = function() {
return "tee-hee!";
}
tests_mock_test_var1 = "original value 1";
tests_mock_test_var2 = "original value 2";
},
'mocking a function restores orignial function afterwards' : function() {
tests_mock.before('mock_me');
tests_mock.after('mock_me');
value_of(mock_me()).should_be("ha-ha!");
},
'not calling a mocked function returns 0' : function() {
tests_mock.before('mock_me');
value_of(tests_mock.after('mock_me').called).should_be(0);
},
'calling a mocked function once returns 1' : function() {
tests_mock.before('mock_me');
mock_me();
value_of(tests_mock.after('mock_me').called).should_be(1);
},
'calling a mocked function 1001 times returns 1001' : function() {
tests_mock.before('mock_me');
for (var i=0; i<1001;i++)
mock_me();
value_of(tests_mock.after('mock_me').called).should_be(1001);
},
'shouldn\'t be able to mock a non-existant function' : function() {
var caught = "no error";
try { tests_mock.before('nonexistant_function') } catch(e) { caught = e.message }
value_of(caught).should_match(/nonexistant_function/);
},
'mocked function should be able to return a hard-coded value' : function() {
tests_mock.before('mock_me', function() { return "hoho" });
var returnValue = mock_me();
value_of(tests_mock.after('mock_me').called).should_be(1);
value_of(returnValue).should_be('hoho');
},
'mocked function should be able to process passed arguments' : function() {
tests_mock.before('mock_me', function(p1,p2,p3,p4,p5) { return p1+p2+p3+p4+p5 });
var returnValue = mock_me(5,3,2,99,101);
var returnValue2 = mock_me(9,10,0,0,1);
value_of(tests_mock.after('mock_me').called).should_be(2);
value_of(returnValue).should_be(210);
value_of(returnValue2).should_be(20);
},
'should be able to mock more than one function at a time' : function() {
tests_mock.before('mock_me', function() { return "called1" });
tests_mock.before('mock_me2', function() { return "called2" });
var returnValue = mock_me();
var returnValue2 = mock_me2();
value_of(returnValue).should_be('called1');
value_of(returnValue2).should_be('called2');
},
'mocked functions should have independent counters' : function() {
tests_mock.before('mock_me');
tests_mock.before('mock_me2');
mock_me();
for (var i=0; i<1001;i++) {
mock_me();
mock_me2();
}
mock_me();
value_of(tests_mock.after('mock_me').called).should_be(1003);
value_of(tests_mock.after('mock_me2').called).should_be(1001);
},
'saving a global variable restores orignial value afterwards' : function() {
var original = tests_mock_test_var1;
tests_mock.save('tests_mock_test_var1');
tests_mock_test_var1 = "foo foo foo";
tests_mock.restore();
value_of(tests_mock_test_var1).should_be(original);
},
});
// ]]>

View File

@@ -0,0 +1,113 @@
// <![CDATA[
describe('Strings', {
'String right': function() {
var actual = "abcdef".right(3);
var expected = "def";
value_of(actual).should_be(expected);
},
'String trim': function() {
var actual = " abcdef ".trim();
var expected = "abcdef";
value_of(actual).should_be(expected);
},
'String undash': function() {
var actual = "background-color".unDash();
var expected = "backgroundColor";
value_of(actual).should_be(expected);
},
'String format with an empty substring array should return input string': function() {
var actual = "hello %0, is your favourite colour red?".format([]);
var expected = "hello , is your favourite colour red?";
value_of(actual).should_be(expected);
},
'String format with a substrings array of correct size (1) should add substrings in the right places': function() {
var actual = "hello %0, is your favourite colour red?".format(["Jon"]);
var expected = "hello Jon, is your favourite colour red?";
value_of(actual).should_be(expected);
},
'String format with a substrings array of more than enough substrings (1 needed) should add substrings in the right places': function() {
var actual = "hello %0, is your favourite colour red?".format(["Jon","rhubarb","rhubarb"]);
var expected = "hello Jon, is your favourite colour red?";
value_of(actual).should_be(expected);
},
'String format with an empty substring array and no %1-type specifiers should return input string': function() {
var actual = "hello Jon, is your favourite colour red?".format([]);
var expected = "hello Jon, is your favourite colour red?";
value_of(actual).should_be(expected);
},
'String format with a substrings array of non-zero size (1) and no %1-type specifiers should return input string': function() {
var actual = "hello Jon, is your favourite colour red?".format(["rhubarb"]);
var expected = "hello Jon, is your favourite colour red?";
value_of(actual).should_be(expected);
},
'String.encodeTiddlyLinkList with null parameter should return null string': function() {
var actual = String.encodeTiddlyLinkList();
var expected = "";
value_of(actual).should_be(expected);
},
'String.encodeTiddlyLinkList with empty array as parameter should return null string': function() {
var actual = String.encodeTiddlyLinkList([]);
var expected = "";
value_of(actual).should_be(expected);
},
'String "abcdefghijklmnopqrstuvwxyz" startsWith "abc"': function() {
value_of("abcdefghijklmnopqrstuvwxyz".startsWith("abc")).should_be(true);
},
'String "abcdefghijklmnopqrstuvwxyz" does not startsWith "def"': function() {
value_of("abcdefghijklmnopqrstuvwxyz".startsWith("def")).should_be(false);
},
'String "abcdefghijklmnopqrstuvwxyz" startsWith ""': function() {
value_of("abcdefghijklmnopqrstuvwxyz".startsWith("")).should_be(true);
}
});
describe('Strings: html encoding/decoding', {
'String should correctly htmlEncode &<>"': function() {
var actual = '&<>"'.htmlEncode();
var expected = '&amp;&lt;&gt;&quot;';
value_of(actual).should_be(expected);
},
'String should correctly htmlDecode &amp;&lt;&gt;&quot;': function() {
var actual = '&amp;&lt;&gt;&quot;'.htmlDecode();
var expected = '&<>"';
value_of(actual).should_be(expected);
},
'htmlEncode followed by htmlDecode of complex string should leave string unchanged': function() {
var s = '&&&""<">>&>&"';
var actual = s.htmlEncode().htmlDecode();
value_of(actual).should_be(s);
}
// NO IT SHOULDN'T! YOU CAN'T DECODE SOMETHING THAT IS NOT ENCODED
//'htmlDecode followed by htmlEncode of complex string should leave string unchanged': function() {
// var s = '&&&""<">>&>&"';
// var actual = s.htmlDecode().htmlEncode();
// value_of(actual).should_be(s);
//}
});
describe('Strings: parseParams', {
'String should correctly parseParams for single name value pair': function() {
var actual = "aName:aValue".parseParams();
var expected = [{"aName":["aValue"]},{name:"aName",value:"aValue"}];
value_of(actual).should_be(expected);
},
'String should correctly parseParams for two name value pairs': function() {
var actual = "aName:'aValue' aName2:'aValue2'".parseParams();
var expected = [{"aName":["aValue"], "aName2":["aValue2"]},{name:"aName",value:"aValue"},{name:"aName2",value:"aValue2"}];
value_of(actual).should_be(expected);
}
});
describe('Strings: encodeTiddlyLink', {
'String should correctly encodeTiddlyLink with no spaces': function() {
var actual = String.encodeTiddlyLink("title");
var expected = "title";
value_of(actual).should_be(expected);
},
'String should correctly encodeTiddlyLink with spaces': function() {
var actual = String.encodeTiddlyLink("the title");
var expected = "[[the title]]";
value_of(actual).should_be(expected);
}
});
// ]]>

View File

@@ -0,0 +1,519 @@
// <![CDATA[
describe('Wikifier: getParser()', {
before_each: function(){
formatter = new Formatter(config.formatters);
},
after_each: function() {
formatter = null;
},
'it should return the default formatter if no tiddler argument is provided': function() {
var actual = getParser(null,null);
console.log(actual);
var expected = formatter;
console.log(expected);
value_of(actual).should_be(expected);
},
'it should return the default formatter if no format argument is provided and the tiddler has no "wikiformat" field and is not tagged with the value of formatTag of a member of config.parsers': function() {
var t = new Tiddler("t");
var actual = getParser(t,null);
var expected = formatter;
value_of(actual).should_be(expected);
},
'it should return the default formatter if a format argument is provided, but does not appear as a value of formatTag of a member of config.parsers; the tiddler has no "wikiformat" field and is not tagged with the value of formatTag from a member of config.parsers': function() {
var t = new Tiddler("t");
var actual = getParser(t,"nomatch");
var expected = formatter;
value_of(actual).should_be(expected);
},
'it should return the default formatter if the tiddler has a "wikiformat" field that does not appear as a value of formatTag of a member of config.parsers; no format argument is provided and the tiddler is not tagged with the value of formatTag from a member of config.parsers': function() {
var t = new Tiddler("t");
t.fields.wikiformat = "nomatch";
var actual = getParser(t,null);
var expected = formatter;
value_of(actual).should_be(expected);
},
'it should return the formatter specified by the "wikiformat" field even if a format tag is provided; no format parameter is provided': function() {
var t = new Tiddler("t");
t.fields.wikiformat = "format_field";
t.tags.push("format_tag");
config.parsers.field = {
format: "format_field"
};
config.parsers.tag = {
formatTag: "format_tag"
};
var actual = getParser(t,null);
var expected = config.parsers.field;
value_of(actual).should_be(expected);
},
'it should return the formatter specified by the format tag; the tiddler has no "wikiformat" field and no format parameter is provided': function() {
var t = new Tiddler("t");
t.tags.push("format_tag");
config.parsers.tag = {
formatTag: "format_tag"
};
var actual = getParser(t,null);
var expected = config.parsers.tag;
value_of(actual).should_be(expected);
},
'it should return the formatter specified by the format parameter even if a format tag and a "wikiformat" field are provided': function() {
var t = new Tiddler("t");
t.fields.wikiformat = "format_field";
t.tags.push("format_tag");
config.parsers.field = {
format: "format_field"
};
config.parsers.tag = {
formatTag: "format_tag"
};
config.parsers.parameter = {
format: "format_parameter"
};
var actual = getParser(t,"format_parameter");
var expected = config.parsers.parameter;
value_of(actual).should_be(expected);
}
});
describe('Wikifier: wikify()', {
before_each: function() {
place = document.createElement("div");
d = document.body.appendChild(place);
d.style.display = "none";
},
after_each: function() {
removeNode(d);
},
'it should not call subWikify() if the "source" parameter is not provided': function() {
var funcToMock = 'Wikifier.prototype.subWikify';
tests_mock.before(funcToMock);
wikify();
var actual = tests_mock.after(funcToMock).called;
value_of(actual).should_be_false();
},
'it should not call subWikify() if the "source" parameter is an empty string': function() {
var funcToMock = 'Wikifier.prototype.subWikify';
tests_mock.before(funcToMock);
var source = "";
wikify(source);
value_of(tests_mock.after(funcToMock).called).should_be_false();
},
'it should call subWikify()': function() {
var funcToMock = 'Wikifier.prototype.subWikify';
tests_mock.before(funcToMock);
var source = "hello";
wikify(source);
value_of(tests_mock.after(funcToMock).called).should_be(true);
}
});
describe('Wikifier: wikifyStatic()', {
'testing input strings for Formatter.characterFormat': function() {
wikifier_input_strings = {
bold:"''bold''",
italic:"//italic//",
underline:"__underline__",
superscript:"^^superscript^^",
subscript:"~~subscript~~",
strikeout:"--strikeout--",
code:"{{{code}}}"
};
wikifier_output_strings = {
bold:"<strong>bold</strong>",
italic:"<em>italic</em>",
underline:"<u>underline</u>",
superscript:"<sup>superscript</sup>",
subscript:"<sub>subscript</sub>",
strikeout:"<strike>strikeout</strike>",
code:"<code>code</code>"
};
formatter = new Formatter(config.formatters);
var actual = "";
var expected = "";
for (var i in wikifier_input_strings) {
actual = wikifyStatic(wikifier_input_strings[i]).toLowerCase();
expected = wikifier_output_strings[i];
value_of(actual).should_be(expected);
}
},
'testing table formatting': function() {
formatter = new Formatter(config.formatters);
var expected = '<table class="twtable"><tbody><tr class="evenrow"><td>a</td><td>b</td></tr><tr class="oddrow"><td>c</td><td>d</td></tr></tbody></table>';
var actual = wikifyStatic("|a|b|\n|c|d|").toLowerCase();
value_of(actual).should_be(expected);
}
/*'table surrounded by character formatting should not cause infinite loop': function() {
formatter = new Formatter(config.formatters);
var actual = wikifyStatic("''|a|b|\n|c|d|''").toLowerCase();
value_of(true).should_be_true(); // just check that above line did not cause infinite loop
}*/
});
describe('Wikifier: wikifyStatic()', {
before_each: function() {
place = document.createElement("div");
d = document.body.appendChild(place);
d.style.display = "none";
source = "some text";
},
after_each: function() {
removeNode(d);
},
'it should return an empty string if source does not exist or is an empty string': function() {
var expected = "";
var actual = wikifyStatic(null);
value_of(actual).should_be(expected);
actual = wikifyStatic("");
value_of(actual).should_be(expected);
},
'it should not require a tiddler to work': function() {
var actual = wikifyStatic(source);
value_of(actual).should_not_be_null();
},
'it should call subWikify() with the pre block as the only parameter': function() {
var funcToMock = 'Wikifier.prototype.subWikify';
tests_mock.before(funcToMock,function() {
tests_mock.frame[funcToMock].funcArgs = arguments;
});
wikifyStatic(source);
var tests_mock_return = tests_mock.after(funcToMock);
var expected = "PRE";
value_of(tests_mock_return.called).should_be(true);
value_of(tests_mock_return.funcArgs.length).should_be(1);
value_of(tests_mock_return.funcArgs[0].nodeName).should_be(expected);
},
'it should return a text string': function() {
var expected = "string";
var actual = typeof wikifyStatic(source);
},
'it should not leave any elements attached to the document body after returning': function() {
var expected = document.body.childNodes.length;
var html = wikifyStatic(source);
var actual = document.body.childNodes.length;
value_of(actual).should_be(expected);
}
});
describe('Wikifier: wikifyPlain', {
before_each: function() {
store = new TiddlyWiki();
loadShadowTiddlers();
store.saveTiddler("t","t","text");
formatter = new Formatter(config.formatters);
},
'it should use the store if only a title parameter is provided': function() {
var actual = wikifyPlain("t");
value_of(actual).should_not_be_null();
},
'it should call wikifyPlainText() if the tiddler exists in the store or is a shadow tiddler': function() {
tests_mock.before('wikifyPlainText');
wikifyPlain("t");
var actual = tests_mock.after('wikifyPlainText').called;
value_of(actual).should_be_true();
},
'it should call wikifyPlainText() if the tiddler is a shadow tiddler': function() {
var t = store.isShadowTiddler("SiteTitle");
value_of(t).should_be_true();
mockVars = tests_mock.before('wikifyPlainText');
wikifyPlain("SiteTitle");
var actual = tests_mock.after('wikifyPlainText').called;
value_of(actual).should_be_true();
},
'it should return an empty string if the tiddler is not in the store or a shadow tiddler': function() {
var tiddler = store.getTiddler("foo");
value_of(tiddler).should_be(null);
var actual = wikifyPlain("foo");
var expected = "";
value_of(actual).should_be(expected);
}
});
describe('Wikifier: wikifyPlainText', {
before_each: function() {
store = new TiddlyWiki();
loadShadowTiddlers();
formatter = new Formatter(config.formatters);
},
'if a limit parameter is provided and the input text is greater in length than the limit, the number of characters generated should equal the limit': function() {
var limit = 5;
var source = "aphraseof21characters";
var actual = wikifyPlainText(source,limit).length;
var expected = limit;
value_of(actual).should_be(expected);
},
'it should call Wikifier.prototype.wikifyPlain()': function() {
tests_mock.before('Wikifier.prototype.wikifyPlain');
wikifyPlainText("hello",1,new Tiddler("temp"));
var actual = tests_mock.after('Wikifier.prototype.wikifyPlain').called;
value_of(actual).should_be_true();
},
'it should take an optional tiddler parameter that sets the context for the wikification': function() {
var tiddler = new Tiddler("temp");
var source = "<<view text>>";
tiddler.text = "the text of a tiddler";
var expected = tiddler.text;
store.saveTiddler("temp","temp",tiddler.text);
var actual = wikifyPlainText(source,null,tiddler);
value_of(actual).should_be(expected);
}
});
describe('Wikifier: highlightify', {
before_each: function() {
output = document.body.appendChild(document.createElement("div"));
source = "test text";
highlightregexp = new RegExp("text","img");
tiddler = new Tiddler("temp");
},
'it should not add anything to the "output" element if the source parameter is empty': function() {
var actual = highlightify(null,output);
value_of(actual).shoufld_be_null;
},
'it should highlight output text by wrapping with a span of class "highlight"': function() {
var expected = 'test <span class="highlight">text</span>';
highlightify(source,output,highlightregexp,tiddler);
// value in IE is: test <SPAN class=highlight>text</SPAN>
// note SPAN is capitals and no quotes
actual = output.innerHTML;
value_of(actual).should_be(expected);
},
after_each: function() {
removeNode(output);
}
});
describe('Wikifier: Wikifier()', {
'it should return a Wikifier object': function() {
var actual = new Wikifier();
value_of(actual instanceof Wikifier).should_be_true();
},
'it should return an object with properties source, output, formatter, nextMatch, autoLinkWikiWords, highlightRegExp, highlightMatch, isStatic, tiddler': function() {
var actual = new Wikifier();
value_of(actual.hasOwnProperty("source")).should_be_true();
value_of(actual.hasOwnProperty("output")).should_be_true();
value_of(actual.hasOwnProperty("formatter")).should_be_true();
value_of(actual.hasOwnProperty("nextMatch")).should_be_true();
value_of(actual.hasOwnProperty("autoLinkWikiWords")).should_be_true();
value_of(actual.hasOwnProperty("highlightRegExp")).should_be_true();
value_of(actual.hasOwnProperty("highlightMatch")).should_be_true();
value_of(actual.hasOwnProperty("isStatic")).should_be_true();
value_of(actual.hasOwnProperty("tiddler")).should_be_true();
}
});
describe('Wikifier: wikifyPlain', {
'it should return the plain text value of the return value of this.subWikify()': function() {
store = new TiddlyWiki();
formatter = new Formatter(config.formatters);
var source = "a StringWith some [[wikitext]] ''inside''";
var w = new Wikifier(source,formatter);
var actual = w.wikifyPlain();
var expected = "a StringWith some wikitext inside";
value_of(actual).should_be(expected);
}
});
describe('Wikifier: subWikify', {
before_each: function() {
formatter = new Formatter(config.formatters);
output = document.body.appendChild(document.createElement("div"));
terminator = "";
w = new Wikifier("test",formatter);
},
'it should call this.subWikifyUnterm if second parameter is not provided': function() {
tests_mock.before('Wikifier.prototype.subWikifyUnterm');
w.subWikify(output);
var actual = tests_mock.after('Wikifier.prototype.subWikifyUnterm').called;
value_of(actual).should_be_true;
},
'it should call this.subWikifyTerm if a second parameter is provided': function() {
tests_mock.before('Wikifier.prototype.subWikifyTerm');
w.subWikify(output,terminator);
var actual = tests_mock.after('Wikifier.prototype.subWikifyTerm').called;
value_of(actual).should_be_true;
},
after_each: function() {
removeNode(output);
delete formatter;
delete terminator;
delete w;
}
});
describe('Wikifier: subWikifyUnterm', {
before_each: function() {
formatter = new Formatter([{
name: "test",
match: "test",
handler: function(w)
{
createTiddlyText(w.output,w.matchText);
}
}]);
output = document.body.appendChild(document.createElement("div"));
source = "some test input for a test of a function";
w = new Wikifier(source,formatter);
},
'it should pass any text that matches the formatter\'s regexp to the correct handler in the formatter': function() {
w.subWikifyUnterm(output);
var actual = output.innerHTML;
var expected = source;
value_of(actual).should_be(expected);
},
'it should output any text before, between or after a match': function() {
tests_mock.before('Wikifier.prototype.outputText');
w.subWikifyUnterm(output);
var actual = tests_mock.after('Wikifier.prototype.outputText').called;
value_of(actual).should_be(3);
actual = output.innerHTML;
var expected = "testtest";
value_of(actual).should_be(expected);
},
after_each: function() {
removeNode(output);
delete formatter;
delete source;
delete w;
}
});
describe('Wikifier: subWikifyTerm', {
before_each: function() {
formatter = new Formatter([{
name: "test",
match: "test",
handler: function(w)
{
createTiddlyText(w.output,w.matchText);
}
}]);
termRegExp = /(\n)/mg;
output = document.body.appendChild(document.createElement("div"));
source = "some test multi-line test input \n for a test of a function";
w = new Wikifier(source,formatter);
},
'it should ignore all input after a match with termRegExp': function() {
w.subWikifyTerm(output,termRegExp);
var actual = output.innerHTML;
var expected = source.substring(0,source.indexOf("\n"));
value_of(actual).should_be(expected);
},
'it should pass any text that matches the formatter\'s regexp to the correct handler in the formatter': function() {
tests_mock.before('formatter.formatters[0].handler');
w.subWikifyTerm(output,termRegExp);
var actual = tests_mock.after('formatter.formatters[0].handler').called;
value_of(actual).should_be(2);
},
'it should output any text before, between or after a formatter match': function() {
tests_mock.before('Wikifier.prototype.outputText');
w.subWikifyTerm(output,termRegExp);
var actual = tests_mock.after('Wikifier.prototype.outputText').called;
value_of(actual).should_be(3);
actual = output.innerHTML;
var expected = "testtest";
value_of(actual).should_be(expected);
},
after_each: function() {
removeNode(output);
delete formatter;
delete termRegExp;
delete source;
delete w;
}
});
describe('Wikifier: outputText', {
before_each: function() {
formatter = new Formatter(config.formatters);
source = "some test input";
highlightRegExp = /test/g;
output = document.body.appendChild(document.createElement("div"));
},
'it should output all the input text if the Wikifier object\'s highlightRegExp property is null': function() {
w = new Wikifier(source,formatter);
w.outputText(output,0,source.length);
var actual = output.innerHTML;
value_of(actual).should_be(source);
},
'it should wrap any text that matched by the Wikifier object\'s highlightRegExp in <span> tags with a class of "highlight"': function() {
w = new Wikifier(source,formatter,highlightRegExp);
w.outputText(output,0,source.length);
var actual = output.innerHTML;
var match = actual.match("<span");
if(!match)
match = actual.match("<SPAN");
var length = match ? match.length : -1;
value_of(length).should_be(1);
},
after_each: function() {
removeNode(output);
delete formatter;
delete source;
delete highlightRegExp;
}
});
// ]]>

View File

@@ -0,0 +1,38 @@
// <![CDATA[
describe('XML: testing framework XML functions', {
'parsing XML returns an object' : function() {
xml = tests_xml.parse('<foo><bar></bar></foo>');
value_of(typeof xml).should_match('object');
},
'documentElement should be an object' : function() {
xml = tests_xml.parse('<foo><bar></bar></foo>');
value_of(typeof xml.documentElement).should_be("object");
},
'DOM should be able to access documentElement nodeName' : function() {
xml = tests_xml.parse('<foo><bar></bar></foo>');
value_of(xml.documentElement.nodeName).should_be("foo");
},
'DOM should be able to access documentElement nodeName from empty document' : function() {
xml = tests_xml.parse('<foo/>');
value_of(xml.documentElement.nodeName).should_be("foo");
},
'DOM should be able to access attribute on document node' : function() {
xml = tests_xml.parse('<foo version="2.0"></foo>');
value_of(xml.documentElement.getAttribute("version")).should_be("2.0");
},
'XPath should be able to access the documentElement' : function() {
xml = tests_xml.parse('<foo>hello</foo>');
value_of(xml.xpath("/foo", "string")).should_be("hello");
},
'XPath should be able to access the documentElement' : function() {
xml = tests_xml.parse('<foo>hello<bar>world</bar></foo>');
value_of(xml.xpath("/foo/bar", "string")).should_be("world");
},
'XPath count of nodeset containing elements' : function() {
xml = tests_xml.parse('<foo><bar/><bar/><bar/></foo>');
value_of(xml.xpath("count(/foo/bar)", "number")).should_be(3);
}
});
// ]]>

View File

@@ -0,0 +1,8 @@
jsspec: BasicTypes.jsspec.js
jsspec: Dom.jsspec.js
jsspec: Macros.jsspec.js
jsspec: Messages.jsspec.js
jsspec: Mocks.jsspec.js
jsspec: Strings.jsspec.js
jsspec: Wikifier.jsspec.js
jsspec: XML.jsspec.js