aboutsummaryrefslogtreecommitdiff
path: root/node_modules/istanbul/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/istanbul/lib/util')
-rw-r--r--node_modules/istanbul/lib/util/factory.js88
-rw-r--r--node_modules/istanbul/lib/util/file-matcher.js76
-rw-r--r--node_modules/istanbul/lib/util/file-writer.js154
-rw-r--r--node_modules/istanbul/lib/util/help-formatter.js30
-rw-r--r--node_modules/istanbul/lib/util/input-error.js12
-rw-r--r--node_modules/istanbul/lib/util/insertion-text.js109
-rw-r--r--node_modules/istanbul/lib/util/meta.js13
-rw-r--r--node_modules/istanbul/lib/util/tree-summarizer.js213
-rw-r--r--node_modules/istanbul/lib/util/writer.js92
-rw-r--r--node_modules/istanbul/lib/util/yui-load-hook.js49
10 files changed, 836 insertions, 0 deletions
diff --git a/node_modules/istanbul/lib/util/factory.js b/node_modules/istanbul/lib/util/factory.js
new file mode 100644
index 000000000..9f3d6f36f
--- /dev/null
+++ b/node_modules/istanbul/lib/util/factory.js
@@ -0,0 +1,88 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var util = require('util'),
+ path = require('path'),
+ fs = require('fs'),
+ abbrev = require('abbrev');
+
+function Factory(kind, dir, allowAbbreviations) {
+ this.kind = kind;
+ this.dir = dir;
+ this.allowAbbreviations = allowAbbreviations;
+ this.classMap = {};
+ this.abbreviations = null;
+}
+
+Factory.prototype = {
+
+ knownTypes: function () {
+ var keys = Object.keys(this.classMap);
+ keys.sort();
+ return keys;
+ },
+
+ resolve: function (abbreviatedType) {
+ if (!this.abbreviations) {
+ this.abbreviations = abbrev(this.knownTypes());
+ }
+ return this.abbreviations[abbreviatedType];
+ },
+
+ register: function (constructor) {
+ var type = constructor.TYPE;
+ if (!type) { throw new Error('Could not register ' + this.kind + ' constructor [no TYPE property]: ' + util.inspect(constructor)); }
+ this.classMap[type] = constructor;
+ this.abbreviations = null;
+ },
+
+ create: function (type, opts) {
+ var allowAbbrev = this.allowAbbreviations,
+ realType = allowAbbrev ? this.resolve(type) : type,
+ Cons;
+
+ Cons = realType ? this.classMap[realType] : null;
+ if (!Cons) { throw new Error('Invalid ' + this.kind + ' [' + type + '], allowed values are ' + this.knownTypes().join(', ')); }
+ return new Cons(opts);
+ },
+
+ loadStandard: function (dir) {
+ var that = this;
+ fs.readdirSync(dir).forEach(function (file) {
+ if (file !== 'index.js' && file.indexOf('.js') === file.length - 3) {
+ try {
+ that.register(require(path.resolve(dir, file)));
+ } catch (ex) {
+ console.error(ex.message);
+ console.error(ex.stack);
+ throw new Error('Could not register ' + that.kind + ' from file ' + file);
+ }
+ }
+ });
+ },
+
+ bindClassMethods: function (Cons) {
+ var tmpKind = this.kind.charAt(0).toUpperCase() + this.kind.substring(1), //ucfirst
+ allowAbbrev = this.allowAbbreviations;
+
+ Cons.mix = Factory.mix;
+ Cons.register = this.register.bind(this);
+ Cons.create = this.create.bind(this);
+ Cons.loadAll = this.loadStandard.bind(this, this.dir);
+ Cons['get' + tmpKind + 'List'] = this.knownTypes.bind(this);
+ if (allowAbbrev) {
+ Cons['resolve' + tmpKind + 'Name'] = this.resolve.bind(this);
+ }
+ }
+};
+
+Factory.mix = function (cons, proto) {
+ Object.keys(proto).forEach(function (key) {
+ cons.prototype[key] = proto[key];
+ });
+};
+
+module.exports = Factory;
+
diff --git a/node_modules/istanbul/lib/util/file-matcher.js b/node_modules/istanbul/lib/util/file-matcher.js
new file mode 100644
index 000000000..986064252
--- /dev/null
+++ b/node_modules/istanbul/lib/util/file-matcher.js
@@ -0,0 +1,76 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var async = require('async'),
+ glob = require('glob'),
+ fs = require('fs'),
+ path = require('path'),
+ seq = 0;
+
+function filesFor(options, callback) {
+ if (!callback && typeof options === 'function') {
+ callback = options;
+ options = null;
+ }
+ options = options || {};
+
+ var root = options.root,
+ includes = options.includes,
+ excludes = options.excludes,
+ realpath = options.realpath,
+ relative = options.relative,
+ opts;
+
+ root = root || process.cwd();
+ includes = includes && Array.isArray(includes) ? includes : [ '**/*.js' ];
+ excludes = excludes && Array.isArray(excludes) ? excludes : [ '**/node_modules/**' ];
+
+ opts = { cwd: root, nodir: true, ignore: excludes };
+ seq += 1;
+ opts['x' + seq + new Date().getTime()] = true; //cache buster for minimatch cache bug
+ glob(includes.join(' '), opts, function (err, files) {
+ if (err) { return callback(err); }
+ if (relative) { return callback(err, files); }
+
+ if (!realpath) {
+ files = files.map(function (file) { return path.resolve(root, file); });
+ return callback(err, files);
+ }
+
+ var realPathCache = module.constructor._realpathCache || {};
+
+ async.map(files, function (file, done) {
+ fs.realpath(path.resolve(root, file), realPathCache, done);
+ }, callback);
+ });
+}
+
+function matcherFor(options, callback) {
+
+ if (!callback && typeof options === 'function') {
+ callback = options;
+ options = null;
+ }
+ options = options || {};
+ options.relative = false; //force absolute paths
+ options.realpath = true; //force real paths (to match Node.js module paths)
+
+ filesFor(options, function (err, files) {
+ var fileMap = {},
+ matchFn;
+ if (err) { return callback(err); }
+ files.forEach(function (file) { fileMap[file] = true; });
+
+ matchFn = function (file) { return fileMap[file]; };
+ matchFn.files = Object.keys(fileMap);
+ return callback(null, matchFn);
+ });
+}
+
+module.exports = {
+ filesFor: filesFor,
+ matcherFor: matcherFor
+};
+
diff --git a/node_modules/istanbul/lib/util/file-writer.js b/node_modules/istanbul/lib/util/file-writer.js
new file mode 100644
index 000000000..3367dcc83
--- /dev/null
+++ b/node_modules/istanbul/lib/util/file-writer.js
@@ -0,0 +1,154 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var path = require('path'),
+ util = require('util'),
+ fs = require('fs'),
+ async = require('async'),
+ mkdirp = require('mkdirp'),
+ writer = require('./writer'),
+ Writer = writer.Writer,
+ ContentWriter = writer.ContentWriter;
+
+function extend(cons, proto) {
+ Object.keys(proto).forEach(function (k) {
+ cons.prototype[k] = proto[k];
+ });
+}
+
+function BufferedContentWriter() {
+ ContentWriter.call(this);
+ this.content = '';
+}
+util.inherits(BufferedContentWriter, ContentWriter);
+
+extend(BufferedContentWriter, {
+ write: function (str) {
+ this.content += str;
+ },
+ getContent: function () {
+ return this.content;
+ }
+});
+
+function StreamContentWriter(stream) {
+ ContentWriter.call(this);
+ this.stream = stream;
+}
+util.inherits(StreamContentWriter, ContentWriter);
+
+extend(StreamContentWriter, {
+ write: function (str) {
+ this.stream.write(str);
+ }
+});
+
+function SyncFileWriter() {
+ Writer.call(this);
+}
+util.inherits(SyncFileWriter, Writer);
+
+extend(SyncFileWriter, {
+ writeFile: function (file, callback) {
+ mkdirp.sync(path.dirname(file));
+ var cw = new BufferedContentWriter();
+ callback(cw);
+ fs.writeFileSync(file, cw.getContent(), 'utf8');
+ },
+ done: function () {
+ this.emit('done'); //everything already done
+ }
+});
+
+function AsyncFileWriter() {
+ this.queue = async.queue(this.processFile.bind(this), 20);
+ this.openFileMap = {};
+}
+
+util.inherits(AsyncFileWriter, Writer);
+
+extend(AsyncFileWriter, {
+ writeFile: function (file, callback) {
+ this.openFileMap[file] = true;
+ this.queue.push({ file: file, callback: callback });
+ },
+ processFile: function (task, cb) {
+ var file = task.file,
+ userCallback = task.callback,
+ that = this,
+ stream,
+ contentWriter;
+
+ mkdirp.sync(path.dirname(file));
+ stream = fs.createWriteStream(file);
+ stream.on('close', function () {
+ delete that.openFileMap[file];
+ cb();
+ that.checkDone();
+ });
+ stream.on('error', function (err) { that.emit('error', err); });
+ contentWriter = new StreamContentWriter(stream);
+ userCallback(contentWriter);
+ stream.end();
+ },
+ done: function () {
+ this.doneCalled = true;
+ this.checkDone();
+ },
+ checkDone: function () {
+ if (!this.doneCalled) { return; }
+ if (Object.keys(this.openFileMap).length === 0) {
+ this.emit('done');
+ }
+ }
+});
+/**
+ * a concrete writer implementation that can write files synchronously or
+ * asynchronously based on the constructor argument passed to it.
+ *
+ * Usage
+ * -----
+ *
+ * var sync = true,
+ * fileWriter = new require('istanbul').FileWriter(sync);
+ *
+ * fileWriter.on('done', function () { console.log('done'); });
+ * fileWriter.copyFile('/foo/bar.jpg', '/baz/bar.jpg');
+ * fileWriter.writeFile('/foo/index.html', function (contentWriter) {
+ * contentWriter.println('<html>');
+ * contentWriter.println('</html>');
+ * });
+ * fileWriter.done(); // will emit the `done` event when all files are written
+ *
+ * @class FileWriter
+ * @extends Writer
+ * @module io
+ * @param sync
+ * @constructor
+ */
+function FileWriter(sync) {
+ Writer.call(this);
+ var that = this;
+ this.delegate = sync ? new SyncFileWriter() : new AsyncFileWriter();
+ this.delegate.on('error', function (err) { that.emit('error', err); });
+ this.delegate.on('done', function () { that.emit('done'); });
+}
+
+util.inherits(FileWriter, Writer);
+
+extend(FileWriter, {
+ copyFile: function (source, dest) {
+ mkdirp.sync(path.dirname(dest));
+ fs.writeFileSync(dest, fs.readFileSync(source));
+ },
+ writeFile: function (file, callback) {
+ this.delegate.writeFile(file, callback);
+ },
+ done: function () {
+ this.delegate.done();
+ }
+});
+
+module.exports = FileWriter; \ No newline at end of file
diff --git a/node_modules/istanbul/lib/util/help-formatter.js b/node_modules/istanbul/lib/util/help-formatter.js
new file mode 100644
index 000000000..8d9136acf
--- /dev/null
+++ b/node_modules/istanbul/lib/util/help-formatter.js
@@ -0,0 +1,30 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var OPT_PREFIX = " ",
+ OPT_START = OPT_PREFIX.length,
+ TEXT_START = 14,
+ STOP = 80,
+ wrap = require('wordwrap')(TEXT_START, STOP),
+ paraWrap = require('wordwrap')(1, STOP);
+
+function formatPara(text) {
+ return paraWrap(text);
+}
+
+function formatOption(option, helpText) {
+ var formattedText = wrap(helpText);
+
+ if (option.length > TEXT_START - OPT_START - 2) {
+ return OPT_PREFIX + option + '\n' + formattedText;
+ } else {
+ return OPT_PREFIX + option + formattedText.substring((OPT_PREFIX + option).length);
+ }
+}
+
+module.exports = {
+ formatPara: formatPara,
+ formatOption: formatOption
+}; \ No newline at end of file
diff --git a/node_modules/istanbul/lib/util/input-error.js b/node_modules/istanbul/lib/util/input-error.js
new file mode 100644
index 000000000..488b71a0d
--- /dev/null
+++ b/node_modules/istanbul/lib/util/input-error.js
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+module.exports.create = function (message) {
+ var err = new Error(message);
+ err.inputError = true;
+ return err;
+};
+
+
diff --git a/node_modules/istanbul/lib/util/insertion-text.js b/node_modules/istanbul/lib/util/insertion-text.js
new file mode 100644
index 000000000..d257643f2
--- /dev/null
+++ b/node_modules/istanbul/lib/util/insertion-text.js
@@ -0,0 +1,109 @@
+/*
+ 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; \ No newline at end of file
diff --git a/node_modules/istanbul/lib/util/meta.js b/node_modules/istanbul/lib/util/meta.js
new file mode 100644
index 000000000..0384459b5
--- /dev/null
+++ b/node_modules/istanbul/lib/util/meta.js
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+var path = require('path'),
+ fs = require('fs'),
+ pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, '..', '..', 'package.json'), 'utf8'));
+
+module.exports = {
+ NAME: pkg.name,
+ VERSION: pkg.version
+};
+
diff --git a/node_modules/istanbul/lib/util/tree-summarizer.js b/node_modules/istanbul/lib/util/tree-summarizer.js
new file mode 100644
index 000000000..df350f50e
--- /dev/null
+++ b/node_modules/istanbul/lib/util/tree-summarizer.js
@@ -0,0 +1,213 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var path = require('path'),
+ SEP = path.sep || '/',
+ utils = require('../object-utils');
+
+function commonArrayPrefix(first, second) {
+ var len = first.length < second.length ? first.length : second.length,
+ i,
+ ret = [];
+ for (i = 0; i < len; i += 1) {
+ if (first[i] === second[i]) {
+ ret.push(first[i]);
+ } else {
+ break;
+ }
+ }
+ return ret;
+}
+
+function findCommonArrayPrefix(args) {
+ if (args.length === 0) {
+ return [];
+ }
+
+ var separated = args.map(function (arg) { return arg.split(SEP); }),
+ ret = separated.pop();
+
+ if (separated.length === 0) {
+ return ret.slice(0, ret.length - 1);
+ } else {
+ return separated.reduce(commonArrayPrefix, ret);
+ }
+}
+
+function Node(fullName, kind, metrics) {
+ this.name = fullName;
+ this.fullName = fullName;
+ this.kind = kind;
+ this.metrics = metrics || null;
+ this.parent = null;
+ this.children = [];
+}
+
+Node.prototype = {
+ displayShortName: function () {
+ return this.relativeName;
+ },
+ fullPath: function () {
+ return this.fullName;
+ },
+ addChild: function (child) {
+ this.children.push(child);
+ child.parent = this;
+ },
+ toJSON: function () {
+ return {
+ name: this.name,
+ relativeName: this.relativeName,
+ fullName: this.fullName,
+ kind: this.kind,
+ metrics: this.metrics,
+ parent: this.parent === null ? null : this.parent.name,
+ children: this.children.map(function (node) { return node.toJSON(); })
+ };
+ }
+};
+
+function TreeSummary(summaryMap, commonPrefix) {
+ this.prefix = commonPrefix;
+ this.convertToTree(summaryMap, commonPrefix);
+}
+
+TreeSummary.prototype = {
+ getNode: function (shortName) {
+ return this.map[shortName];
+ },
+ convertToTree: function (summaryMap, arrayPrefix) {
+ var nodes = [],
+ rootPath = arrayPrefix.join(SEP) + SEP,
+ root = new Node(rootPath, 'dir'),
+ tmp,
+ tmpChildren,
+ seen = {},
+ filesUnderRoot = false;
+
+ seen[rootPath] = root;
+ Object.keys(summaryMap).forEach(function (key) {
+ var metrics = summaryMap[key],
+ node,
+ parentPath,
+ parent;
+ node = new Node(key, 'file', metrics);
+ seen[key] = node;
+ nodes.push(node);
+ parentPath = path.dirname(key) + SEP;
+ if (parentPath === SEP + SEP || parentPath === '.' + SEP) {
+ parentPath = SEP + '__root__' + SEP;
+ }
+ parent = seen[parentPath];
+ if (!parent) {
+ parent = new Node(parentPath, 'dir');
+ root.addChild(parent);
+ seen[parentPath] = parent;
+ }
+ parent.addChild(node);
+ if (parent === root) { filesUnderRoot = true; }
+ });
+
+ if (filesUnderRoot && arrayPrefix.length > 0) {
+ arrayPrefix.pop(); //start at one level above
+ tmp = root;
+ tmpChildren = tmp.children;
+ tmp.children = [];
+ root = new Node(arrayPrefix.join(SEP) + SEP, 'dir');
+ root.addChild(tmp);
+ tmpChildren.forEach(function (child) {
+ if (child.kind === 'dir') {
+ root.addChild(child);
+ } else {
+ tmp.addChild(child);
+ }
+ });
+ }
+ this.fixupNodes(root, arrayPrefix.join(SEP) + SEP);
+ this.calculateMetrics(root);
+ this.root = root;
+ this.map = {};
+ this.indexAndSortTree(root, this.map);
+ },
+
+ fixupNodes: function (node, prefix, parent) {
+ var that = this;
+ if (node.name.indexOf(prefix) === 0) {
+ node.name = node.name.substring(prefix.length);
+ }
+ if (node.name.charAt(0) === SEP) {
+ node.name = node.name.substring(1);
+ }
+ if (parent) {
+ if (parent.name !== '__root__' + SEP) {
+ node.relativeName = node.name.substring(parent.name.length);
+ } else {
+ node.relativeName = node.name;
+ }
+ } else {
+ node.relativeName = node.name.substring(prefix.length);
+ }
+ node.children.forEach(function (child) {
+ that.fixupNodes(child, prefix, node);
+ });
+ },
+ calculateMetrics: function (entry) {
+ var that = this,
+ fileChildren;
+ if (entry.kind !== 'dir') {return; }
+ entry.children.forEach(function (child) {
+ that.calculateMetrics(child);
+ });
+ entry.metrics = utils.mergeSummaryObjects.apply(
+ null,
+ entry.children.map(function (child) { return child.metrics; })
+ );
+ // calclulate "java-style" package metrics where there is no hierarchy
+ // across packages
+ fileChildren = entry.children.filter(function (n) { return n.kind !== 'dir'; });
+ if (fileChildren.length > 0) {
+ entry.packageMetrics = utils.mergeSummaryObjects.apply(
+ null,
+ fileChildren.map(function (child) { return child.metrics; })
+ );
+ } else {
+ entry.packageMetrics = null;
+ }
+ },
+ indexAndSortTree: function (node, map) {
+ var that = this;
+ map[node.name] = node;
+ node.children.sort(function (a, b) {
+ a = a.relativeName;
+ b = b.relativeName;
+ return a < b ? -1 : a > b ? 1 : 0;
+ });
+ node.children.forEach(function (child) {
+ that.indexAndSortTree(child, map);
+ });
+ },
+ toJSON: function () {
+ return {
+ prefix: this.prefix,
+ root: this.root.toJSON()
+ };
+ }
+};
+
+function TreeSummarizer() {
+ this.summaryMap = {};
+}
+
+TreeSummarizer.prototype = {
+ addFileCoverageSummary: function (filePath, metrics) {
+ this.summaryMap[filePath] = metrics;
+ },
+ getTreeSummary: function () {
+ var commonArrayPrefix = findCommonArrayPrefix(Object.keys(this.summaryMap));
+ return new TreeSummary(this.summaryMap, commonArrayPrefix);
+ }
+};
+
+module.exports = TreeSummarizer;
diff --git a/node_modules/istanbul/lib/util/writer.js b/node_modules/istanbul/lib/util/writer.js
new file mode 100644
index 000000000..f5e68293c
--- /dev/null
+++ b/node_modules/istanbul/lib/util/writer.js
@@ -0,0 +1,92 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+var util = require('util'),
+ EventEmitter = require('events').EventEmitter;
+
+function extend(cons, proto) {
+ Object.keys(proto).forEach(function (k) {
+ cons.prototype[k] = proto[k];
+ });
+}
+
+/**
+ * abstract interfaces for writing content
+ * @class ContentWriter
+ * @module io
+ * @main io
+ * @constructor
+ */
+//abstract interface for writing content
+function ContentWriter() {
+}
+
+ContentWriter.prototype = {
+ /**
+ * writes the specified string as-is
+ * @method write
+ * @param {String} str the string to write
+ */
+ write: /* istanbul ignore next: abstract method */ function (/* str */) {
+ throw new Error('write: must be overridden');
+ },
+ /**
+ * writes the specified string with a newline at the end
+ * @method println
+ * @param {String} str the string to write
+ */
+ println: function (str) { this.write(str + '\n'); }
+};
+
+/**
+ * abstract interface for writing files and assets. The caller is expected to
+ * call `done` on the writer after it has finished writing all the required
+ * files. The writer is an event-emitter that emits a `done` event when `done`
+ * is called on it *and* all files have successfully been written.
+ *
+ * @class Writer
+ * @constructor
+ */
+function Writer() {
+ EventEmitter.call(this);
+}
+
+util.inherits(Writer, EventEmitter);
+
+extend(Writer, {
+ /**
+ * allows writing content to a file using a callback that is passed a content writer
+ * @method writeFile
+ * @param {String} file the name of the file to write
+ * @param {Function} callback the callback that is called as `callback(contentWriter)`
+ */
+ writeFile: /* istanbul ignore next: abstract method */ function (/* file, callback */) {
+ throw new Error('writeFile: must be overridden');
+ },
+ /**
+ * copies a file from source to destination
+ * @method copyFile
+ * @param {String} source the file to copy, found on the file system
+ * @param {String} dest the destination path
+ */
+ copyFile: /* istanbul ignore next: abstract method */ function (/* source, dest */) {
+ throw new Error('copyFile: must be overridden');
+ },
+ /**
+ * marker method to indicate that the caller is done with this writer object
+ * The writer is expected to emit a `done` event only after this method is called
+ * and it is truly done.
+ * @method done
+ */
+ done: /* istanbul ignore next: abstract method */ function () {
+ throw new Error('done: must be overridden');
+ }
+});
+
+module.exports = {
+ Writer: Writer,
+ ContentWriter: ContentWriter
+};
+
diff --git a/node_modules/istanbul/lib/util/yui-load-hook.js b/node_modules/istanbul/lib/util/yui-load-hook.js
new file mode 100644
index 000000000..9b1365d7a
--- /dev/null
+++ b/node_modules/istanbul/lib/util/yui-load-hook.js
@@ -0,0 +1,49 @@
+/*
+ Copyright (c) 2012, Yahoo! Inc. All rights reserved.
+ Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
+ */
+
+//EXPERIMENTAL code: do not rely on this in anyway until the docs say it is allowed
+
+var path = require('path'),
+ yuiRegexp = /yui-nodejs\.js$/;
+
+module.exports = function (matchFn, transformFn, verbose) {
+ return function (file) {
+ if (!file.match(yuiRegexp)) {
+ return;
+ }
+ var YMain = require(file),
+ YUI,
+ loaderFn,
+ origGet;
+
+ if (YMain.YUI) {
+ YUI = YMain.YUI;
+ loaderFn = YUI.Env && YUI.Env.mods && YUI.Env.mods['loader-base'] ? YUI.Env.mods['loader-base'].fn : null;
+ if (!loaderFn) { return; }
+ if (verbose) { console.log('Applying YUI load post-hook'); }
+ YUI.Env.mods['loader-base'].fn = function (Y) {
+ loaderFn.call(null, Y);
+ origGet = Y.Get._exec;
+ Y.Get._exec = function (data, url, cb) {
+ if (matchFn(url) || matchFn(path.resolve(url))) { //allow for relative paths as well
+ if (verbose) {
+ console.log('Transforming [' + url + ']');
+ }
+ try {
+ data = transformFn(data, url);
+ } catch (ex) {
+ console.error('Error transforming: ' + url + ' return original code');
+ console.error(ex.message || ex);
+ if (ex.stack) { console.error(ex.stack); }
+ }
+ }
+ return origGet.call(Y, data, url, cb);
+ };
+ return Y;
+ };
+ }
+ };
+};
+