istanbul
Version:
Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests
109 lines (96 loc) • 3.12 kB
JavaScript
/*
Copyright (c) 2012, Yahoo! Inc. All rights reserved.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
function InsertionText(text, consumeBlanks) {
this.text = text;
this.origLength = text.length;
this.offsets = [];
this.consumeBlanks = consumeBlanks;
this.startPos = this.findFirstNonBlank();
this.endPos = this.findLastNonBlank();
}
var WHITE_RE = /[ \f\n\r\t\v\u00A0\u2028\u2029]/;
InsertionText.prototype = {
findFirstNonBlank: function () {
var pos = -1,
text = this.text,
len = text.length,
i;
for (i = 0; i < len; i += 1) {
if (!text.charAt(i).match(WHITE_RE)) {
pos = i;
break;
}
}
return pos;
},
findLastNonBlank: function () {
var text = this.text,
len = text.length,
pos = text.length + 1,
i;
for (i = len - 1; i >= 0; i -= 1) {
if (!text.charAt(i).match(WHITE_RE)) {
pos = i;
break;
}
}
return pos;
},
originalLength: function () {
return this.origLength;
},
insertAt: function (col, str, insertBefore, consumeBlanks) {
consumeBlanks = typeof consumeBlanks === 'undefined' ? this.consumeBlanks : consumeBlanks;
col = col > this.originalLength() ? this.originalLength() : col;
col = col < 0 ? 0 : col;
if (consumeBlanks) {
if (col <= this.startPos) {
col = 0;
}
if (col > this.endPos) {
col = this.origLength;
}
}
var len = str.length,
offset = this.findOffset(col, len, insertBefore),
realPos = col + offset,
text = this.text;
this.text = text.substring(0, realPos) + str + text.substring(realPos);
return this;
},
findOffset: function (pos, len, insertBefore) {
var offsets = this.offsets,
offsetObj,
cumulativeOffset = 0,
i;
for (i = 0; i < offsets.length; i += 1) {
offsetObj = offsets[i];
if (offsetObj.pos < pos || (offsetObj.pos === pos && !insertBefore)) {
cumulativeOffset += offsetObj.len;
}
if (offsetObj.pos >= pos) {
break;
}
}
if (offsetObj && offsetObj.pos === pos) {
offsetObj.len += len;
} else {
offsets.splice(i, 0, { pos: pos, len: len });
}
return cumulativeOffset;
},
wrap: function (startPos, startText, endPos, endText, consumeBlanks) {
this.insertAt(startPos, startText, true, consumeBlanks);
this.insertAt(endPos, endText, false, consumeBlanks);
return this;
},
wrapLine: function (startText, endText) {
this.wrap(0, startText, this.originalLength(), endText);
},
toString: function () {
return this.text;
}
};
module.exports = InsertionText;