This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
4.7 KiB
167 lines
4.7 KiB
/* |
|
Copyright 2012-2015, Yahoo Inc. |
|
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. |
|
*/ |
|
"use strict"; |
|
|
|
var util = require('util'); |
|
/** |
|
* An object with methods that are called during the traversal of the coverage tree. |
|
* A visitor has the following methods that are called during tree traversal. |
|
* |
|
* * `onStart(root, state)` - called before traversal begins |
|
* * `onSummary(node, state)` - called for every summary node |
|
* * `onDetail(node, state)` - called for every detail node |
|
* * `onSummaryEnd(node, state)` - called after all children have been visited for |
|
* a summary node. |
|
* * `onEnd(root, state)` - called after traversal ends |
|
* |
|
* @param delegate - a partial visitor that only implements the methods of interest |
|
* The visitor object supplies the missing methods as noops. For example, reports |
|
* that only need the final coverage summary need implement `onStart` and nothing |
|
* else. Reports that use only detailed coverage information need implement `onDetail` |
|
* and nothing else. |
|
* @constructor |
|
*/ |
|
function Visitor(delegate) { |
|
this.delegate = delegate; |
|
} |
|
|
|
['Start', 'End', 'Summary', 'SummaryEnd', 'Detail' ].forEach(function (k) { |
|
var f = 'on' + k; |
|
Visitor.prototype[f] = function (node, state) { |
|
if (this.delegate[f] && typeof this.delegate[f] === 'function') { |
|
this.delegate[f].call(this.delegate, node, state); |
|
} |
|
}; |
|
}); |
|
|
|
function CompositeVisitor(visitors) { |
|
if (!Array.isArray(visitors)) { |
|
visitors = [visitors]; |
|
} |
|
this.visitors = visitors.map(function (v) { |
|
if (v instanceof Visitor) { |
|
return v; |
|
} |
|
return new Visitor(v); |
|
}); |
|
} |
|
|
|
util.inherits(CompositeVisitor, Visitor); |
|
|
|
['Start', 'Summary', 'SummaryEnd', 'Detail', 'End'].forEach(function (k) { |
|
var f = 'on' + k; |
|
CompositeVisitor.prototype[f] = function (node, state) { |
|
this.visitors.forEach(function (v) { |
|
v[f](node, state); |
|
}); |
|
}; |
|
}); |
|
|
|
function Node() { |
|
} |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getQualifiedName = function () { |
|
throw new Error('getQualifiedName must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getRelativeName = function () { |
|
throw new Error('getRelativeName must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.isRoot = function () { |
|
return !this.getParent(); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getParent = function () { |
|
throw new Error('getParent must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getChildren = function () { |
|
throw new Error('getChildren must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.isSummary = function () { |
|
throw new Error('isSummary must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getCoverageSummary = function (/* filesOnly */) { |
|
throw new Error('getCoverageSummary must be overridden'); |
|
}; |
|
|
|
/* istanbul ignore next: abstract method */ |
|
Node.prototype.getFileCoverage = function () { |
|
throw new Error('getFileCoverage must be overridden'); |
|
}; |
|
/** |
|
* visit all nodes depth-first from this node down. Note that `onStart` |
|
* and `onEnd` are never called on the visitor even if the current |
|
* node is the root of the tree. |
|
* @param visitor a full visitor that is called during tree traversal |
|
* @param state optional state that is passed around |
|
*/ |
|
Node.prototype.visit = function (visitor, state) { |
|
|
|
var that = this, |
|
visitChildren = function () { |
|
that.getChildren().forEach(function (child) { |
|
child.visit(visitor, state); |
|
}); |
|
}; |
|
|
|
if (this.isSummary()) { |
|
visitor.onSummary(this, state); |
|
} else { |
|
visitor.onDetail(this, state); |
|
} |
|
|
|
visitChildren(); |
|
|
|
if (this.isSummary()) { |
|
visitor.onSummaryEnd(this, state); |
|
} |
|
}; |
|
|
|
/** |
|
* abstract base class for a coverage tree. |
|
* @constructor |
|
*/ |
|
function Tree() { |
|
} |
|
|
|
/** |
|
* returns the root node of the tree |
|
*/ |
|
/* istanbul ignore next: abstract method */ |
|
Tree.prototype.getRoot = function () { |
|
throw new Error('getRoot must be overridden'); |
|
}; |
|
|
|
/** |
|
* visits the tree depth-first with the supplied partial visitor |
|
* @param visitor - a potentially partial visitor |
|
* @param state - the state to be passed around during tree traversal |
|
*/ |
|
Tree.prototype.visit = function (visitor, state) { |
|
if (!(visitor instanceof Visitor)) { |
|
visitor = new Visitor(visitor); |
|
} |
|
visitor.onStart(this.getRoot(), state); |
|
this.getRoot().visit(visitor, state); |
|
visitor.onEnd(this.getRoot(), state); |
|
}; |
|
|
|
module.exports = { |
|
Tree: Tree, |
|
Node: Node, |
|
Visitor: Visitor, |
|
CompositeVisitor: CompositeVisitor |
|
};
|
|
|