siesta-lite
Version:
Stress-free JavaScript unit testing and functional testing tool, works in NodeJS and browsers
224 lines (156 loc) • 6.8 kB
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
<script type="text/javascript">
function highlight() {
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
}
</script>
</head>
<body onload="prettyPrint(); highlight();">
<pre class="prettyprint lang-js">/*
Siesta 5.6.1
Copyright(c) 2009-2022 Bryntum AB
https://bryntum.com/contact
https://bryntum.com/products/siesta/license
*/
Class('Ariadne.QueryFinder', {
does : [
Ariadne.QueryFinder.TreeWalker
],
has : {
recognizers : Joose.I.Array,
identifiers : Joose.I.Array,
directChildIdentifier : null,
// `true` to always include an #id segment of the 1st parent node with #id in the query
// even if its not required
// idea is that since some parent has #id, element "belongs" to that parent, and the query
// will be more robust
// note, that id's of the following parents won't be included
enableMandatoryId : true
},
methods : {
initialize : function () {
this.initRecognizers()
this.initIdentifiers()
this.recognizers.sort(function (r1, r2) {
return r2.priority - r1.priority
})
this.identifiers.sort(function (r1, r2) {
return r2.priority - r1.priority
})
},
addRecognizer : function (instance) {
this.recognizers.push(instance)
return instance
},
addIdentifier : function (instance) {
this.identifiers.push(instance)
return instance
},
initRecognizers : function () {
},
initIdentifiers : function () {
},
findQuery : function (target, root) {
return this.findQueries(target, root, { singleOnly : true })[ 0 ]
},
findQueries : function (target, root, options) {
// TUNE
// console.time('TOTAL')
if (!target) throw new Error("No target")
if (!root) throw new Error("No root")
if (target == root) throw new Error("Can't find query - target and root are the same")
if (this.contains(target, root)) throw new Error("Can't find query - root is contained within target, need to swap the arguments?")
var maze = /*MAZE = */new Ariadne.QueryFinder.Maze({ finder : this })
maze.buildVertices(target, root)
maze.buildEdges()
var res = maze.findAllPaths(options)
// TUNE
// console.timeEnd('TOTAL')
return res
},
forAllCombinations : function (segments, func) {
var combinator = new Ariadne.QueryFinder.Combinator({ elements : segments })
return combinator.forAllCombinations(func)
},
bisect : function (leftIndex, rightIndex, func) {
while (leftIndex <= rightIndex) {
var middleIndex = Math.round((leftIndex + rightIndex) / 2)
var res = func(middleIndex)
if (res === false) return false
if (leftIndex == rightIndex) return
if (res == null) throw new Error("Unknown bisect direction")
if (res < 0) rightIndex = middleIndex - 1
if (res > 0) leftIndex = middleIndex + 1
}
},
combineSegments : function (segments, allowDanglingDirectChild) {
var queryComponents = []
var totalWeight = 0
var ids = []
var processed = {}
var hasId = false
for (var i = 0; i < segments.length; i++ ) {
var segment = segments[ i ]
var segmentId = segment.id
if (processed[ segmentId ]) continue
processed[ segmentId ] = true
ids.push(segmentId)
var index = segment.index
var queryComponent = queryComponents[ index ]
if (!queryComponent) {
queryComponent = queryComponents[ index ] = { segments : [], hasLeading : false, child : false }
}
totalWeight += segment.weight
if (segment.leading)
if (queryComponent.hasLeading)
return null
else {
queryComponent.hasLeading = true
queryComponent.segments.unshift(segment.query)
}
else
queryComponent.segments.push(segment.query)
if (segment.child) queryComponent.child = true
if (segment.isId) hasId = true
}
var query = ''
for (var i = queryComponents.length - 1; i >= 0; i--) {
var queryComponent = queryComponents[ i ]
if (queryComponent) {
if (!allowDanglingDirectChild && queryComponent.child && (i == queryComponents.length - 1 || !queryComponents[ i + 1 ])) throw new Error("Invalid direct child component")
var component = queryComponent.segments.join('')
if (!query)
query = component
else
query += (queryComponent.child ? ' > ' : ' ') + component
}
}
ids.sort(function (a, b) { return a - b })
return {
query : query,
weight : totalWeight,
hasId : hasId,
hash : ids.join('')
}
},
doQuery : function (query, root) {
throw new Error("Abstract method called: `doQuery`")
},
verifyQuery : function (query, target, root) {
var queryRes = this.doQuery(query, root)
return queryRes.length == 1 && queryRes[ 0 ] == target
}
}
});
</pre>
</body>
</html>