1
0
Fork 0

new version

This commit is contained in:
Frank Celler 2014-02-09 18:25:44 +01:00
parent 157217503a
commit 13b361555f
113 changed files with 21344 additions and 3084 deletions

View File

@ -1,4 +1,4 @@
underscore: 1.5.2 working
coffee-script: 1.6.3 'compile' supported
sinon: 1.7.3
coffee-script: 1.7.1 'compile' supported
sinon: 1.8.1
buster-format: 0.5.6

View File

@ -1,4 +1,4 @@
Copyright (c) 2009-2013 Jeremy Ashkenas
Copyright (c) 2009-2014 Jeremy Ashkenas
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation

View File

@ -1,12 +1,11 @@
{
} } {
{ { } }
} }{ {
{ }{ } } _____ __ __
( }{ }{ { ) / ____| / _|/ _|
{ }{ }{ { } / ____| / _|/ _|
.- { { } { }} -. | | ___ | |_| |_ ___ ___
( ( } { } { } } ) | | / _ \| _| _/ _ \/ _ \
( { } { } { } } ) | | / _ \| _| _/ _ \/ _ \
|`-..________ ..-'| | |___| (_) | | | || __/ __/
| | \_____\___/|_| |_| \___|\___|
| ;--.
@ -22,13 +21,13 @@
CoffeeScript is a little language that compiles into JavaScript.
Install Node.js, and then the CoffeeScript compiler:
sudo bin/cake install
Or, if you have the Node Package Manager installed:
If you have the Node Package Manager installed:
npm install -g coffee-script
(Leave off the -g if you don't wish to install globally.)
Or, if you don't wish to use npm:
sudo bin/cake install
Execute a script:
coffee /path/to/script.coffee
@ -47,5 +46,5 @@
The source repository:
git://github.com/jashkenas/coffee-script.git
All contributors are listed here:
Top 100 contributors are listed here:
http://github.com/jashkenas/coffee-script/contributors

View File

@ -1,79 +0,0 @@
require 'rubygems'
require 'erb'
require 'fileutils'
require 'rake/testtask'
require 'json'
desc "Build the documentation page"
task :doc do
source = 'documentation/index.html.erb'
child = fork { exec "bin/coffee -bcw -o documentation/js documentation/coffee/*.coffee" }
at_exit { Process.kill("INT", child) }
Signal.trap("INT") { exit }
loop do
mtime = File.stat(source).mtime
if !@mtime || mtime > @mtime
rendered = ERB.new(File.read(source)).result(binding)
File.open('index.html', 'w+') {|f| f.write(rendered) }
end
@mtime = mtime
sleep 1
end
end
desc "Build coffee-script-source gem"
task :gem do
require 'rubygems'
require 'rubygems/package'
gemspec = Gem::Specification.new do |s|
s.name = 'coffee-script-source'
s.version = JSON.parse(File.read('package.json'))["version"]
s.date = Time.now.strftime("%Y-%m-%d")
s.homepage = "http://jashkenas.github.com/coffee-script/"
s.summary = "The CoffeeScript Compiler"
s.description = <<-EOS
CoffeeScript is a little language that compiles into JavaScript.
Underneath all of those embarrassing braces and semicolons,
JavaScript has always had a gorgeous object model at its heart.
CoffeeScript is an attempt to expose the good parts of JavaScript
in a simple way.
EOS
s.files = [
'lib/coffee_script/coffee-script.js',
'lib/coffee_script/source.rb'
]
s.authors = ['Jeremy Ashkenas']
s.email = 'jashkenas@gmail.com'
s.rubyforge_project = 'coffee-script-source'
s.license = "MIT"
end
file = File.open("coffee-script-source.gem", "w")
Gem::Package.open(file, 'w') do |pkg|
pkg.metadata = gemspec.to_yaml
path = "lib/coffee_script/source.rb"
contents = <<-ERUBY
module CoffeeScript
module Source
def self.bundled_path
File.expand_path("../coffee-script.js", __FILE__)
end
end
end
ERUBY
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
contents = File.read("extras/coffee-script.js")
path = "lib/coffee_script/coffee-script.js"
pkg.add_file_simple(path, 0644, contents.size) do |tar_io|
tar_io.write(contents)
end
end
end

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var CoffeeScript, compile, runScripts,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
@ -41,15 +41,18 @@
options.sourceMap = true;
options.inline = true;
_ref = CoffeeScript.compile(code, options), js = _ref.js, v3SourceMap = _ref.v3SourceMap;
return "" + js + "\n//@ sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//@ sourceURL=coffeescript";
return "" + js + "\n//# sourceMappingURL=data:application/json;base64," + (btoa(unescape(encodeURIComponent(v3SourceMap)))) + "\n//# sourceURL=coffeescript";
};
}
CoffeeScript.load = function(url, callback, options) {
CoffeeScript.load = function(url, callback, options, hold) {
var xhr;
if (options == null) {
options = {};
}
if (hold == null) {
hold = false;
}
options.sourceFiles = [url];
xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP') : new window.XMLHttpRequest();
xhr.open('GET', url, true);
@ -57,15 +60,18 @@
xhr.overrideMimeType('text/plain');
}
xhr.onreadystatechange = function() {
var _ref;
var param, _ref;
if (xhr.readyState === 4) {
if ((_ref = xhr.status) === 0 || _ref === 200) {
CoffeeScript.run(xhr.responseText, options);
param = [xhr.responseText, options];
if (!hold) {
CoffeeScript.run.apply(CoffeeScript, param);
}
} else {
throw new Error("Could not load " + url);
}
if (callback) {
return callback();
return callback(param);
}
}
};
@ -73,7 +79,7 @@
};
runScripts = function() {
var coffees, coffeetypes, execute, index, length, s, scripts;
var coffees, coffeetypes, execute, i, index, s, script, scripts, _fn, _i, _len;
scripts = window.document.getElementsByTagName('script');
coffeetypes = ['text/coffeescript', 'text/literate-coffeescript'];
coffees = (function() {
@ -88,25 +94,35 @@
return _results;
})();
index = 0;
length = coffees.length;
(execute = function() {
var mediatype, options, script;
script = coffees[index++];
mediatype = script != null ? script.type : void 0;
if (__indexOf.call(coffeetypes, mediatype) >= 0) {
options = {
literate: mediatype === 'text/literate-coffeescript'
};
if (script.src) {
return CoffeeScript.load(script.src, execute, options);
} else {
options.sourceFiles = ['embedded'];
CoffeeScript.run(script.innerHTML, options);
return execute();
}
execute = function() {
var param;
param = coffees[index];
if (param instanceof Array) {
CoffeeScript.run.apply(CoffeeScript, param);
index++;
return execute();
}
})();
return null;
};
_fn = function(script, i) {
var options;
options = {
literate: script.type === coffeetypes[1]
};
if (script.src) {
return CoffeeScript.load(script.src, function(param) {
coffees[i] = param;
return execute();
}, options, true);
} else {
options.sourceFiles = ['embedded'];
return coffees[i] = [script.innerHTML, options];
}
};
for (i = _i = 0, _len = coffees.length; _i < _len; i = ++_i) {
script = coffees[i];
_fn(script, i);
}
return execute();
};
if (window.addEventListener) {

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var CoffeeScript, cakefileDirectory, existsSync, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
var CoffeeScript, cakefileDirectory, fatalError, fs, helpers, missingTask, oparse, options, optparse, path, printTasks, switches, tasks;
fs = require('fs');
@ -12,8 +12,6 @@
CoffeeScript = require('./coffee-script');
existsSync = fs.existsSync || path.existsSync;
tasks = {};
options = {};
@ -101,7 +99,7 @@
cakefileDirectory = function(dir) {
var parent;
if (existsSync(path.join(dir, 'Cakefile'))) {
if (fs.existsSync(path.join(dir, 'Cakefile'))) {
return dir;
}
parent = path.normalize(path.join(dir, '..'));

View File

@ -1,7 +1,8 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var Lexer, Module, SourceMap, child_process, compile, ext, findExtension, fork, formatSourcePosition, fs, helpers, lexer, loadFile, parser, patchStackTrace, patched, path, sourceMaps, vm, _i, _len, _ref,
__hasProp = {}.hasOwnProperty;
var Lexer, SourceMap, compile, formatSourcePosition, fs, getSourceMap, helpers, lexer, parser, path, sourceMaps, vm, withPrettyErrors,
__hasProp = {}.hasOwnProperty,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
fs = require('fs');
@ -9,8 +10,6 @@
path = require('path');
child_process = require('child_process');
Lexer = require('./lexer').Lexer;
parser = require('./parser').parser;
@ -19,16 +18,31 @@
SourceMap = require('./sourcemap');
exports.VERSION = '1.6.3';
exports.VERSION = '1.7.1';
exports.FILE_EXTENSIONS = ['.coffee', '.litcoffee', '.coffee.md'];
exports.helpers = helpers;
exports.compile = compile = function(code, options) {
var answer, currentColumn, currentLine, fragment, fragments, header, js, map, merge, newLines, _i, _len;
if (options == null) {
options = {};
}
merge = helpers.merge;
withPrettyErrors = function(fn) {
return function(code, options) {
var err;
if (options == null) {
options = {};
}
try {
return fn.call(this, code, options);
} catch (_error) {
err = _error;
throw helpers.updateSyntaxError(err, code, options.filename);
}
};
};
exports.compile = compile = withPrettyErrors(function(code, options) {
var answer, currentColumn, currentLine, extend, fragment, fragments, header, js, map, merge, newLines, _i, _len;
merge = helpers.merge, extend = helpers.extend;
options = extend({}, options);
if (options.sourceMap) {
map = new SourceMap;
}
@ -52,7 +66,11 @@
}
newLines = helpers.count(fragment.code, "\n");
currentLine += newLines;
currentColumn = fragment.code.length - (newLines ? fragment.code.lastIndexOf("\n") : 0);
if (newLines) {
currentColumn = fragment.code.length - (fragment.code.lastIndexOf("\n") + 1);
} else {
currentColumn += fragment.code.length;
}
}
js += fragment.code;
}
@ -70,40 +88,35 @@
} else {
return js;
}
};
});
exports.tokens = function(code, options) {
exports.tokens = withPrettyErrors(function(code, options) {
return lexer.tokenize(code, options);
};
});
exports.nodes = function(source, options) {
exports.nodes = withPrettyErrors(function(source, options) {
if (typeof source === 'string') {
return parser.parse(lexer.tokenize(source, options));
} else {
return parser.parse(source);
}
};
});
exports.run = function(code, options) {
var answer, mainModule;
var answer, dir, mainModule, _ref;
if (options == null) {
options = {};
}
mainModule = require.main;
if (options.sourceMap == null) {
options.sourceMap = true;
}
mainModule.filename = process.argv[1] = options.filename ? fs.realpathSync(options.filename) : '.';
mainModule.moduleCache && (mainModule.moduleCache = {});
mainModule.paths = require('module')._nodeModulePaths(path.dirname(fs.realpathSync(options.filename || '.')));
dir = options.filename ? path.dirname(fs.realpathSync(options.filename)) : fs.realpathSync('.');
mainModule.paths = require('module')._nodeModulePaths(dir);
if (!helpers.isCoffee(mainModule.filename) || require.extensions) {
answer = compile(code, options);
patchStackTrace();
sourceMaps[mainModule.filename] = answer.sourceMap;
return mainModule._compile(answer.js, mainModule.filename);
} else {
return mainModule._compile(code, mainModule.filename);
code = (_ref = answer.js) != null ? _ref : answer;
}
return mainModule._compile(code, mainModule.filename);
};
exports["eval"] = function(code, options) {
@ -169,69 +182,29 @@
}
};
loadFile = function(module, filename) {
var answer, raw, stripped;
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
answer = compile(stripped, {
filename: filename,
sourceMap: true,
literate: helpers.isLiterate(filename)
});
sourceMaps[filename] = answer.sourceMap;
return module._compile(answer.js, filename);
exports.register = function() {
return require('./register');
};
if (require.extensions) {
_ref = ['.coffee', '.litcoffee', '.coffee.md'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ext = _ref[_i];
require.extensions[ext] = loadFile;
exports._compileFile = function(filename, sourceMap) {
var answer, err, raw, stripped;
if (sourceMap == null) {
sourceMap = false;
}
Module = require('module');
findExtension = function(filename) {
var curExtension, extensions;
extensions = path.basename(filename).split('.');
if (extensions[0] === '') {
extensions.shift();
}
while (extensions.shift()) {
curExtension = '.' + extensions.join('.');
if (Module._extensions[curExtension]) {
return curExtension;
}
}
return '.js';
};
Module.prototype.load = function(filename) {
var extension;
this.filename = filename;
this.paths = Module._nodeModulePaths(path.dirname(filename));
extension = findExtension(filename);
Module._extensions[extension](this, filename);
return this.loaded = true;
};
}
if (child_process) {
fork = child_process.fork;
child_process.fork = function(path, args, options) {
var execPath;
if (args == null) {
args = [];
}
if (options == null) {
options = {};
}
execPath = helpers.isCoffee(path) ? 'coffee' : null;
if (!Array.isArray(args)) {
args = [];
options = args || {};
}
options.execPath || (options.execPath = execPath);
return fork(path, args, options);
};
}
raw = fs.readFileSync(filename, 'utf8');
stripped = raw.charCodeAt(0) === 0xFEFF ? raw.substring(1) : raw;
try {
answer = compile(stripped, {
filename: filename,
sourceMap: sourceMap,
literate: helpers.isLiterate(filename)
});
} catch (_error) {
err = _error;
throw helpers.updateSyntaxError(err, stripped, filename);
}
return answer;
};
lexer = new Lexer;
@ -241,6 +214,7 @@
token = this.tokens[this.pos++];
if (token) {
tag = token[0], this.yytext = token[1], this.yylloc = token[2];
this.errorToken = token.origin || token;
this.yylineno = this.yylloc.first_line;
} else {
tag = '';
@ -259,52 +233,12 @@
parser.yy = require('./nodes');
parser.yy.parseError = function(message, _arg) {
var token;
var errorLoc, errorTag, errorText, errorToken, token, tokens, _ref;
token = _arg.token;
message = "unexpected " + (token === 1 ? 'end of input' : token);
return helpers.throwSyntaxError(message, parser.lexer.yylloc);
};
patched = false;
sourceMaps = {};
patchStackTrace = function() {
var mainModule;
if (patched) {
return;
}
patched = true;
mainModule = require.main;
return Error.prepareStackTrace = function(err, stack) {
var frame, frames, getSourceMapping, sourceFiles, _ref1;
sourceFiles = {};
getSourceMapping = function(filename, line, column) {
var answer, sourceMap;
sourceMap = sourceMaps[filename];
if (sourceMap) {
answer = sourceMap.sourceLocation([line - 1, column - 1]);
}
if (answer) {
return [answer[0] + 1, answer[1] + 1];
} else {
return null;
}
};
frames = (function() {
var _j, _len1, _results;
_results = [];
for (_j = 0, _len1 = stack.length; _j < _len1; _j++) {
frame = stack[_j];
if (frame.getFunction() === exports.run) {
break;
}
_results.push(" at " + (formatSourcePosition(frame, getSourceMapping)));
}
return _results;
})();
return "" + err.name + ": " + ((_ref1 = err.message) != null ? _ref1 : '') + "\n" + (frames.join('\n')) + "\n";
};
_ref = parser.lexer, errorToken = _ref.errorToken, tokens = _ref.tokens;
errorTag = errorToken[0], errorText = errorToken[1], errorLoc = errorToken[2];
errorText = errorToken === tokens[tokens.length - 1] ? 'end of input' : errorTag === 'INDENT' || errorTag === 'OUTDENT' ? 'indentation' : helpers.nameWhitespaceCharacter(errorText);
return helpers.throwSyntaxError("unexpected " + errorText, errorLoc);
};
formatSourcePosition = function(frame, getSourceMapping) {
@ -326,7 +260,7 @@
line = frame.getLineNumber();
column = frame.getColumnNumber();
source = getSourceMapping(fileName, line, column);
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] + ", <js>:" + line + ":" + column : "" + fileName + ":" + line + ":" + column;
fileLocation = source ? "" + fileName + ":" + source[0] + ":" + source[1] : "" + fileName + ":" + line + ":" + column;
}
functionName = frame.getFunctionName();
isConstructor = frame.isConstructor();
@ -355,4 +289,47 @@
}
};
sourceMaps = {};
getSourceMap = function(filename) {
var answer, _ref;
if (sourceMaps[filename]) {
return sourceMaps[filename];
}
if (_ref = path != null ? path.extname(filename) : void 0, __indexOf.call(exports.FILE_EXTENSIONS, _ref) < 0) {
return;
}
answer = exports._compileFile(filename, true);
return sourceMaps[filename] = answer.sourceMap;
};
Error.prepareStackTrace = function(err, stack) {
var frame, frames, getSourceMapping, _ref;
getSourceMapping = function(filename, line, column) {
var answer, sourceMap;
sourceMap = getSourceMap(filename);
if (sourceMap) {
answer = sourceMap.sourceLocation([line - 1, column - 1]);
}
if (answer) {
return [answer[0] + 1, answer[1] + 1];
} else {
return null;
}
};
frames = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = stack.length; _i < _len; _i++) {
frame = stack[_i];
if (frame.getFunction() === exports.run) {
break;
}
_results.push(" at " + (formatSourcePosition(frame, getSourceMapping)));
}
return _results;
})();
return "" + err.name + ": " + ((_ref = err.message) != null ? _ref : '') + "\n" + (frames.join('\n')) + "\n";
};
}).call(this);

View File

@ -1,6 +1,7 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, exists, forkNode, fs, helpers, hidden, joinTimeout, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, sourceCode, sources, spawn, timeLog, unwatchDir, usage, useWinPathSep, version, wait, watch, watchDir, watchers, writeJs, _ref;
var BANNER, CoffeeScript, EventEmitter, SWITCHES, compileJoin, compileOptions, compilePath, compileScript, compileStdio, exec, findDirectoryIndex, forkNode, fs, helpers, hidden, joinTimeout, mkdirp, notSources, optionParser, optparse, opts, outputPath, parseOptions, path, printLine, printTokens, printWarn, removeSource, removeSourceDir, silentUnlink, sourceCode, sources, spawn, timeLog, usage, useWinPathSep, version, wait, watch, watchDir, watchedDirs, writeJs, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
fs = require('fs');
@ -12,12 +13,12 @@
CoffeeScript = require('./coffee-script');
mkdirp = require('mkdirp');
_ref = require('child_process'), spawn = _ref.spawn, exec = _ref.exec;
EventEmitter = require('events').EventEmitter;
exists = fs.exists || path.exists;
useWinPathSep = path.sep === '\\';
helpers.extend(CoffeeScript, new EventEmitter);
@ -36,7 +37,7 @@
BANNER = 'Usage: coffee [options] path/to/script.coffee -- [args]\n\nIf called without options, `coffee` will run your script.';
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
SWITCHES = [['-b', '--bare', 'compile without a top-level function wrapper'], ['-c', '--compile', 'compile to JavaScript and save as .js files'], ['-e', '--eval', 'pass a string from the command line as input'], ['-h', '--help', 'display this help message'], ['-i', '--interactive', 'run an interactive CoffeeScript REPL'], ['-j', '--join [FILE]', 'concatenate the source CoffeeScript before compiling'], ['-m', '--map', 'generate source map and save as .map files'], ['-n', '--nodes', 'print out the parse tree that the parser produces'], ['--nodejs [ARGS]', 'pass options directly to the "node" binary'], ['--no-header', 'suppress the "Generated by" header'], ['-o', '--output [DIR]', 'set the output directory for compiled JavaScript'], ['-p', '--print', 'print out the compiled JavaScript'], ['-s', '--stdio', 'listen for and compile scripts over stdio'], ['-l', '--literate', 'treat stdio as literate style coffee-script'], ['-t', '--tokens', 'print out the tokens that the lexer/rewriter produce'], ['-v', '--version', 'display the version number'], ['-w', '--watch', 'watch scripts for changes and rerun commands']];
opts = {};
@ -46,13 +47,16 @@
notSources = {};
watchers = {};
watchedDirs = {};
optionParser = null;
exports.run = function() {
var literals, source, _i, _len, _results;
var literals, replCliOpts, source, _i, _len, _ref1, _results;
parseOptions();
replCliOpts = {
useGlobal: true
};
if (opts.nodejs) {
return forkNode();
}
@ -63,94 +67,125 @@
return version();
}
if (opts.interactive) {
return require('./repl').start();
}
if (opts.watch && !fs.watch) {
return printWarn("The --watch feature depends on Node v0.6.0+. You are running " + process.version + ".");
return require('./repl').start(replCliOpts);
}
if (opts.stdio) {
return compileStdio();
}
if (opts["eval"]) {
return compileScript(null, sources[0]);
return compileScript(null, opts["arguments"][0]);
}
if (!sources.length) {
return require('./repl').start();
if (!opts["arguments"].length) {
return require('./repl').start(replCliOpts);
}
literals = opts.run ? sources.splice(1) : [];
literals = opts.run ? opts["arguments"].splice(1) : [];
process.argv = process.argv.slice(0, 2).concat(literals);
process.argv[0] = 'coffee';
if (opts.output) {
opts.output = path.resolve(opts.output);
}
if (opts.join) {
opts.join = path.resolve(opts.join);
}
_ref1 = opts["arguments"];
_results = [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
source = sources[_i];
_results.push(compilePath(source, true, path.normalize(source)));
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
source = _ref1[_i];
source = path.resolve(source);
_results.push(compilePath(source, true, source));
}
return _results;
};
compilePath = function(source, topLevel, base) {
return fs.stat(source, function(err, stats) {
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
var code, err, file, files, stats, _i, _len, _results;
if (__indexOf.call(sources, source) >= 0 || watchedDirs[source] || !topLevel && (notSources[source] || hidden(source))) {
return;
}
try {
stats = fs.statSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
console.error("File not found: " + source);
process.exit(1);
}
if (stats.isDirectory() && path.dirname(source) !== 'node_modules') {
if (opts.watch) {
watchDir(source, base);
}
return fs.readdir(source, function(err, files) {
var file, index, _ref1, _ref2;
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
return;
}
index = sources.indexOf(source);
files = files.filter(function(file) {
return !hidden(file);
});
[].splice.apply(sources, [index, index - index + 1].concat(_ref1 = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(path.join(source, file));
}
return _results;
})())), _ref1;
[].splice.apply(sourceCode, [index, index - index + 1].concat(_ref2 = files.map(function() {
return null;
}))), _ref2;
return files.forEach(function(file) {
return compilePath(path.join(source, file), false, base);
});
});
} else if (topLevel || helpers.isCoffee(source)) {
if (opts.watch) {
watch(source, base);
}
return fs.readFile(source, function(err, code) {
if (err && err.code !== 'ENOENT') {
throw err;
}
if ((err != null ? err.code : void 0) === 'ENOENT') {
return;
}
return compileScript(source, code.toString(), base);
});
} else {
throw err;
}
if (stats.isDirectory()) {
if (path.basename(source) === 'node_modules') {
notSources[source] = true;
return removeSource(source, base);
return;
}
});
if (opts.run) {
compilePath(findDirectoryIndex(source), topLevel, base);
return;
}
if (opts.watch) {
watchDir(source, base);
}
try {
files = fs.readdirSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
return;
} else {
throw err;
}
}
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(compilePath(path.join(source, file), false, base));
}
return _results;
} else if (topLevel || helpers.isCoffee(source)) {
sources.push(source);
sourceCode.push(null);
delete notSources[source];
if (opts.watch) {
watch(source, base);
}
try {
code = fs.readFileSync(source);
} catch (_error) {
err = _error;
if (err.code === 'ENOENT') {
return;
} else {
throw err;
}
}
return compileScript(source, code.toString(), base);
} else {
return notSources[source] = true;
}
};
findDirectoryIndex = function(source) {
var err, ext, index, _i, _len, _ref1;
_ref1 = CoffeeScript.FILE_EXTENSIONS;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
ext = _ref1[_i];
index = path.join(source, "index" + ext);
try {
if ((fs.statSync(index)).isFile()) {
return index;
}
} catch (_error) {
err = _error;
if (err.code !== 'ENOENT') {
throw err;
}
}
}
console.error("Missing index.coffee or index.litcoffee in " + source);
return process.exit(1);
};
compileScript = function(file, input, base) {
var compiled, err, message, o, options, t, task, useColors;
var compiled, err, message, o, options, t, task;
if (base == null) {
base = null;
}
@ -168,6 +203,7 @@
} else if (o.nodes) {
return printLine(CoffeeScript.nodes(t.input, t.options).toString().trim());
} else if (o.run) {
CoffeeScript.register();
return CoffeeScript.run(t.input, t.options);
} else if (o.join && t.file !== o.join) {
if (helpers.isLiterate(file)) {
@ -195,8 +231,7 @@
if (CoffeeScript.listeners('failure').length) {
return;
}
useColors = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS;
message = helpers.prettyErrorMessage(err, file || '[stdin]', input, useColors);
message = err.stack || ("" + err);
if (o.watch) {
return printLine(message + '\x07');
} else {
@ -237,24 +272,23 @@
};
watch = function(source, base) {
var compile, compileTimeout, e, prevStats, rewatch, watchErr, watcher;
var compile, compileTimeout, err, prevStats, rewatch, startWatcher, watchErr, watcher;
watcher = null;
prevStats = null;
compileTimeout = null;
watchErr = function(e) {
if (e.code === 'ENOENT') {
if (sources.indexOf(source) === -1) {
return;
}
try {
rewatch();
return compile();
} catch (_error) {
e = _error;
removeSource(source, base, true);
return compileJoin();
}
} else {
throw e;
watchErr = function(err) {
if (err.code !== 'ENOENT') {
throw err;
}
if (__indexOf.call(sources, source) < 0) {
return;
}
try {
rewatch();
return compile();
} catch (_error) {
removeSource(source, base);
return compileJoin();
}
};
compile = function() {
@ -278,119 +312,130 @@
});
});
};
try {
watcher = fs.watch(source, compile);
} catch (_error) {
e = _error;
watchErr(e);
}
return rewatch = function() {
startWatcher = function() {
return watcher = fs.watch(source).on('change', compile).on('error', function(err) {
if (err.code !== 'EPERM') {
throw err;
}
return removeSource(source, base);
});
};
rewatch = function() {
if (watcher != null) {
watcher.close();
}
return watcher = fs.watch(source, compile);
return startWatcher();
};
try {
return startWatcher();
} catch (_error) {
err = _error;
return watchErr(err);
}
};
watchDir = function(source, base) {
var e, readdirTimeout, watcher;
var err, readdirTimeout, startWatcher, stopWatcher, watcher;
watcher = null;
readdirTimeout = null;
try {
return watcher = fs.watch(source, function() {
startWatcher = function() {
return watcher = fs.watch(source).on('error', function(err) {
if (err.code !== 'EPERM') {
throw err;
}
return stopWatcher();
}).on('change', function() {
clearTimeout(readdirTimeout);
return readdirTimeout = wait(25, function() {
return fs.readdir(source, function(err, files) {
var file, _i, _len, _results;
if (err) {
if (err.code !== 'ENOENT') {
throw err;
}
watcher.close();
return unwatchDir(source, base);
var err, file, files, _i, _len, _results;
try {
files = fs.readdirSync(source);
} catch (_error) {
err = _error;
if (err.code !== 'ENOENT') {
throw err;
}
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
if (!(!hidden(file) && !notSources[file])) {
continue;
}
file = path.join(source, file);
if (sources.some(function(s) {
return s.indexOf(file) >= 0;
})) {
continue;
}
sources.push(file);
sourceCode.push(null);
_results.push(compilePath(file, false, base));
}
return _results;
});
return stopWatcher();
}
_results = [];
for (_i = 0, _len = files.length; _i < _len; _i++) {
file = files[_i];
_results.push(compilePath(path.join(source, file), false, base));
}
return _results;
});
});
};
stopWatcher = function() {
watcher.close();
return removeSourceDir(source, base);
};
watchedDirs[source] = true;
try {
return startWatcher();
} catch (_error) {
e = _error;
if (e.code !== 'ENOENT') {
throw e;
err = _error;
if (err.code !== 'ENOENT') {
throw err;
}
}
};
unwatchDir = function(source, base) {
var file, prevSources, toRemove, _i, _len;
prevSources = sources.slice(0);
toRemove = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = sources.length; _i < _len; _i++) {
file = sources[_i];
if (file.indexOf(source) >= 0) {
_results.push(file);
}
removeSourceDir = function(source, base) {
var file, sourcesChanged, _i, _len;
delete watchedDirs[source];
sourcesChanged = false;
for (_i = 0, _len = sources.length; _i < _len; _i++) {
file = sources[_i];
if (!(source === path.dirname(file))) {
continue;
}
return _results;
})();
for (_i = 0, _len = toRemove.length; _i < _len; _i++) {
file = toRemove[_i];
removeSource(file, base, true);
removeSource(file, base);
sourcesChanged = true;
}
if (!sources.some(function(s, i) {
return prevSources[i] !== s;
})) {
return;
if (sourcesChanged) {
return compileJoin();
}
return compileJoin();
};
removeSource = function(source, base, removeJs) {
var index, jsPath;
removeSource = function(source, base) {
var index;
index = sources.indexOf(source);
sources.splice(index, 1);
sourceCode.splice(index, 1);
if (removeJs && !opts.join) {
jsPath = outputPath(source, base);
return exists(jsPath, function(itExists) {
if (itExists) {
return fs.unlink(jsPath, function(err) {
if (err && err.code !== 'ENOENT') {
throw err;
}
return timeLog("removed " + source);
});
}
});
if (!opts.join) {
silentUnlink(outputPath(source, base));
silentUnlink(outputPath(source, base, '.map'));
return timeLog("removed " + source);
}
};
silentUnlink = function(path) {
var err, _ref1;
try {
return fs.unlinkSync(path);
} catch (_error) {
err = _error;
if ((_ref1 = err.code) !== 'ENOENT' && _ref1 !== 'EPERM') {
throw err;
}
}
};
outputPath = function(source, base, extension) {
var baseDir, basename, dir, srcDir;
var basename, dir, srcDir;
if (extension == null) {
extension = ".js";
}
basename = helpers.baseFileName(source, true, useWinPathSep);
srcDir = path.dirname(source);
baseDir = base === '.' ? srcDir : srcDir.substring(base.length);
dir = opts.output ? path.join(opts.output, baseDir) : srcDir;
if (!opts.output) {
dir = srcDir;
} else if (source === base) {
dir = opts.output;
} else {
dir = path.join(opts.output, path.relative(base, srcDir));
}
return path.join(dir, basename + extension);
};
@ -407,7 +452,7 @@
js = ' ';
}
if (generatedSourceMap) {
js = "" + js + "\n/*\n//@ sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n*/\n";
js = "" + js + "\n//# sourceMappingURL=" + (helpers.baseFileName(sourceMapPath, false, useWinPathSep)) + "\n";
}
fs.writeFile(jsPath, js, function(err) {
if (err) {
@ -425,11 +470,11 @@
});
}
};
return exists(jsDir, function(itExists) {
return fs.exists(jsDir, function(itExists) {
if (itExists) {
return compile();
} else {
return exec("mkdir -p " + jsDir, compile);
return mkdirp(jsDir, compile);
}
});
};
@ -459,17 +504,12 @@
};
parseOptions = function() {
var i, o, source, _i, _len;
var o;
optionParser = new optparse.OptionParser(SWITCHES, BANNER);
o = opts = optionParser.parse(process.argv.slice(2));
o.compile || (o.compile = !!o.output);
o.run = !(o.compile || o.print || o.map);
o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
sources = o["arguments"];
for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
source = sources[i];
sourceCode[i] = null;
}
return o.print = !!(o.print || (o["eval"] || o.stdio && o.compile));
};
compileOptions = function(filename, base) {
@ -478,7 +518,7 @@
filename: filename,
literate: opts.literate || helpers.isLiterate(filename),
bare: opts.bare,
header: opts.compile,
header: opts.compile && !opts['no-header'],
sourceMap: opts.map
};
if (filename) {
@ -504,15 +544,18 @@
};
forkNode = function() {
var args, nodeArgs;
var args, nodeArgs, p;
nodeArgs = opts.nodejs.split(/\s+/);
args = process.argv.slice(1);
args.splice(args.indexOf('--nodejs'), 2);
return spawn(process.execPath, nodeArgs.concat(args), {
p = spawn(process.execPath, nodeArgs.concat(args), {
cwd: process.cwd(),
env: process.env,
customFds: [0, 1, 2]
});
return p.on('exit', function(code) {
return process.exit(code);
});
};
usage = function() {

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var Parser, alt, alternatives, grammar, name, o, operators, token, tokens, unwrap;
@ -32,7 +32,7 @@
Root: [
o('', function() {
return new Block;
}), o('Body'), o('Block TERMINATOR')
}), o('Body')
],
Body: [
o('Line', function() {
@ -96,8 +96,7 @@
return new Value($1);
}), o('ObjAssignable : Expression', function() {
return new Assign(LOC(1)(new Value($1)), $3, 'object');
}), o('ObjAssignable :\
INDENT Expression OUTDENT', function() {
}), o('ObjAssignable : INDENT Expression OUTDENT', function() {
return new Assign(LOC(1)(new Value($1)), $4, 'object');
}), o('Comment')
],
@ -149,6 +148,8 @@
return new Param($1, null, true);
}), o('ParamVar = Expression', function() {
return new Param($1, $3);
}), o('...', function() {
return new Expansion;
})
],
ParamVar: [o('Identifier'), o('ThisProperty'), o('Array'), o('Object')],
@ -328,7 +329,11 @@
return $1.concat($4);
})
],
Arg: [o('Expression'), o('Splat')],
Arg: [
o('Expression'), o('Splat'), o('...', function() {
return new Expansion;
})
],
SimpleArgs: [
o('Expression'), o('SimpleArgs , Expression', function() {
return [].concat($1, $3);
@ -514,9 +519,9 @@
type: $1
});
}), o('IfBlock ELSE IF Expression Block', function() {
return $1.addElse(new If($4, $5, {
return $1.addElse(LOC(3, 5)(new If($4, $5, {
type: $3
}));
})));
})
],
If: [
@ -537,14 +542,16 @@
Operation: [
o('UNARY Expression', function() {
return new Op($1, $2);
}), o('UNARY_MATH Expression', function() {
return new Op($1, $2);
}), o('- Expression', (function() {
return new Op('-', $2);
}), {
prec: 'UNARY'
prec: 'UNARY_MATH'
}), o('+ Expression', (function() {
return new Op('+', $2);
}), {
prec: 'UNARY'
prec: 'UNARY_MATH'
}), o('-- SimpleAssignable', function() {
return new Op('--', $2);
}), o('++ SimpleAssignable', function() {
@ -561,6 +568,8 @@
return new Op('-', $1, $3);
}), o('Expression MATH Expression', function() {
return new Op($2, $1, $3);
}), o('Expression ** Expression', function() {
return new Op($2, $1, $3);
}), o('Expression SHIFT Expression', function() {
return new Op($2, $1, $3);
}), o('Expression COMPARE Expression', function() {
@ -573,14 +582,11 @@
} else {
return new Op($2, $1, $3);
}
}), o('SimpleAssignable COMPOUND_ASSIGN\
Expression', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN Expression', function() {
return new Assign($1, $3, $2);
}), o('SimpleAssignable COMPOUND_ASSIGN\
INDENT Expression OUTDENT', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN INDENT Expression OUTDENT', function() {
return new Assign($1, $4, $2);
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR\
Expression', function() {
}), o('SimpleAssignable COMPOUND_ASSIGN TERMINATOR Expression', function() {
return new Assign($1, $4, $2);
}), o('SimpleAssignable EXTENDS Expression', function() {
return new Extends($1, $3);
@ -588,7 +594,7 @@
]
};
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['left', 'POST_IF']];
tokens = [];

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var buildLocationData, extend, flatten, last, repeat, _ref;
var buildLocationData, extend, flatten, last, repeat, syntaxErrorToString, _ref;
exports.starts = function(string, literal, start) {
return literal === string.substr(start, literal.length);
@ -167,7 +167,7 @@
pathSep = useWinPathSep ? /\\|\// : /\//;
parts = file.split(pathSep);
file = parts[parts.length - 1];
if (!stripExt) {
if (!(stripExt && file.indexOf('.') >= 0)) {
return file;
}
parts = file.split('.');
@ -188,36 +188,65 @@
exports.throwSyntaxError = function(message, location) {
var error;
if (location.last_line == null) {
location.last_line = location.first_line;
}
if (location.last_column == null) {
location.last_column = location.first_column;
}
error = new SyntaxError(message);
error.location = location;
error.toString = syntaxErrorToString;
error.stack = error.toString();
throw error;
};
exports.prettyErrorMessage = function(error, fileName, code, useColors) {
var codeLine, colorize, end, first_column, first_line, last_column, last_line, marker, message, start, _ref1;
if (!error.location) {
return error.stack || ("" + error);
exports.updateSyntaxError = function(error, code, filename) {
if (error.toString === syntaxErrorToString) {
error.code || (error.code = code);
error.filename || (error.filename = filename);
error.stack = error.toString();
}
_ref1 = error.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column;
codeLine = code.split('\n')[first_line];
return error;
};
syntaxErrorToString = function() {
var codeLine, colorize, colorsEnabled, end, filename, first_column, first_line, last_column, last_line, marker, start, _ref1, _ref2;
if (!(this.code && this.location)) {
return Error.prototype.toString.call(this);
}
_ref1 = this.location, first_line = _ref1.first_line, first_column = _ref1.first_column, last_line = _ref1.last_line, last_column = _ref1.last_column;
if (last_line == null) {
last_line = first_line;
}
if (last_column == null) {
last_column = first_column;
}
filename = this.filename || '[stdin]';
codeLine = this.code.split('\n')[first_line];
start = first_column;
end = first_line === last_line ? last_column + 1 : codeLine.length;
marker = repeat(' ', start) + repeat('^', end - start);
if (useColors) {
if (typeof process !== "undefined" && process !== null) {
colorsEnabled = process.stdout.isTTY && !process.env.NODE_DISABLE_COLORS;
}
if ((_ref2 = this.colorful) != null ? _ref2 : colorsEnabled) {
colorize = function(str) {
return "\x1B[1;31m" + str + "\x1B[0m";
};
codeLine = codeLine.slice(0, start) + colorize(codeLine.slice(start, end)) + codeLine.slice(end);
marker = colorize(marker);
}
message = "" + fileName + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + error.message + "\n" + codeLine + "\n" + marker;
return message;
return "" + filename + ":" + (first_line + 1) + ":" + (first_column + 1) + ": error: " + this.message + "\n" + codeLine + "\n" + marker;
};
exports.nameWhitespaceCharacter = function(string) {
switch (string) {
case ' ':
return 'space';
case '\n':
return 'newline';
case '\r':
return 'carriage return';
case '\t':
return 'tab';
default:
return string;
}
};
}).call(this);

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var key, val, _ref;

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDENTABLE_CLOSERS, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, UNARY_MATH, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, repeat, starts, throwSyntaxError, _ref, _ref1,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
@ -17,6 +17,7 @@
}
this.literate = opts.literate;
this.indent = 0;
this.baseIndent = 0;
this.indebt = 0;
this.outdebt = 0;
this.indents = [];
@ -165,30 +166,25 @@
};
Lexer.prototype.stringToken = function() {
var match, octalEsc, string;
switch (this.chunk.charAt(0)) {
var octalEsc, quote, string, trimmed;
switch (quote = this.chunk.charAt(0)) {
case "'":
if (!(match = SIMPLESTR.exec(this.chunk))) {
return 0;
}
string = match[0];
this.token('STRING', string.replace(MULTILINER, '\\\n'), 0, string.length);
string = SIMPLESTR.exec(this.chunk)[0];
break;
case '"':
if (!(string = this.balancedString(this.chunk, '"'))) {
return 0;
}
if (0 < string.indexOf('#{', 1)) {
this.interpolateString(string.slice(1, -1), {
strOffset: 1,
lexedLength: string.length
});
} else {
this.token('STRING', this.escapeLines(string, 0, string.length));
}
break;
default:
return 0;
string = this.balancedString(this.chunk, '"');
}
if (!string) {
return 0;
}
trimmed = this.removeNewlines(string.slice(1, -1));
if (quote === '"' && 0 < string.indexOf('#{', 1)) {
this.interpolateString(trimmed, {
strOffset: 1,
lexedLength: string.length
});
} else {
this.token('STRING', quote + this.escapeLines(trimmed) + quote, 0, string.length);
}
if (octalEsc = /^(?:\\.|[^\\])*\\(?:0[0-7]|[1-7])/.test(string)) {
this.error("octal escape sequences " + string + " are not allowed");
@ -248,8 +244,7 @@
if (this.chunk.charAt(0) !== '/') {
return 0;
}
if (match = HEREGEX.exec(this.chunk)) {
length = this.heregexToken(match);
if (length = this.heregexToken()) {
return length;
}
prev = last(this.tokens);
@ -260,21 +255,24 @@
return 0;
}
_ref3 = match, match = _ref3[0], regex = _ref3[1], flags = _ref3[2];
if (regex === '//') {
return 0;
}
if (regex.slice(0, 2) === '/*') {
this.error('regular expressions cannot begin with `*`');
}
if (regex === '//') {
regex = '/(?:)/';
}
this.token('REGEX', "" + regex + flags, 0, match.length);
return match.length;
};
Lexer.prototype.heregexToken = function(match) {
var body, flags, flagsOffset, heregex, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
Lexer.prototype.heregexToken = function() {
var body, flags, flagsOffset, heregex, match, plusToken, prev, re, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (!(match = HEREGEX.exec(this.chunk))) {
return 0;
}
heregex = match[0], body = match[1], flags = match[2];
if (0 > body.indexOf('#{')) {
re = body.replace(HEREGEX_OMIT, '').replace(/\//g, '\\/');
re = this.escapeLines(body.replace(HEREGEX_OMIT, '$1$2').replace(/\//g, '\\/'), true);
if (re.match(/^\*/)) {
this.error('regular expressions cannot begin with `*`');
}
@ -293,7 +291,7 @@
if (tag === 'TOKENS') {
tokens.push.apply(tokens, value);
} else if (tag === 'NEOSTRING') {
if (!(value = value.replace(HEREGEX_OMIT, ''))) {
if (!(value = value.replace(HEREGEX_OMIT, '$1$2'))) {
continue;
}
value = value.replace(/\\/g, '\\\\');
@ -346,37 +344,48 @@
this.suppressNewlines();
return indent.length;
}
if (!this.tokens.length) {
this.baseIndent = this.indent = size;
return indent.length;
}
diff = size - this.indent + this.outdebt;
this.token('INDENT', diff, indent.length - size, size);
this.indents.push(diff);
this.ends.push('OUTDENT');
this.outdebt = this.indebt = 0;
this.indent = size;
} else if (size < this.baseIndent) {
this.error('missing indentation', indent.length);
} else {
this.indebt = 0;
this.outdentToken(this.indent - size, noNewlines, indent.length);
}
this.indent = size;
return indent.length;
};
Lexer.prototype.outdentToken = function(moveOut, noNewlines, outdentLength) {
var dent, len;
var decreasedIndent, dent, lastIndent, _ref2;
decreasedIndent = this.indent - moveOut;
while (moveOut > 0) {
len = this.indents.length - 1;
if (this.indents[len] === void 0) {
lastIndent = this.indents[this.indents.length - 1];
if (!lastIndent) {
moveOut = 0;
} else if (this.indents[len] === this.outdebt) {
} else if (lastIndent === this.outdebt) {
moveOut -= this.outdebt;
this.outdebt = 0;
} else if (this.indents[len] < this.outdebt) {
this.outdebt -= this.indents[len];
moveOut -= this.indents[len];
} else if (lastIndent < this.outdebt) {
this.outdebt -= lastIndent;
moveOut -= lastIndent;
} else {
dent = this.indents.pop() + this.outdebt;
moveOut -= dent;
if (outdentLength && (_ref2 = this.chunk[outdentLength], __indexOf.call(INDENTABLE_CLOSERS, _ref2) >= 0)) {
decreasedIndent -= dent - moveOut;
moveOut = dent;
}
this.outdebt = 0;
this.pair('OUTDENT');
this.token('OUTDENT', dent, 0, outdentLength);
this.token('OUTDENT', moveOut, 0, outdentLength);
moveOut -= dent;
}
}
if (dent) {
@ -388,6 +397,7 @@
if (!(this.tag() === 'TERMINATOR' || noNewlines)) {
this.token('TERMINATOR', '\n', outdentLength, 0);
}
this.indent = decreasedIndent;
return this;
};
@ -457,6 +467,8 @@
tag = 'COMPOUND_ASSIGN';
} else if (__indexOf.call(UNARY, value) >= 0) {
tag = 'UNARY';
} else if (__indexOf.call(UNARY_MATH, value) >= 0) {
tag = 'UNARY_MATH';
} else if (__indexOf.call(SHIFT, value) >= 0) {
tag = 'SHIFT';
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
@ -586,18 +598,14 @@
};
Lexer.prototype.interpolateString = function(str, options) {
var column, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
var column, errorToken, expr, heredoc, i, inner, interpolated, len, letter, lexedLength, line, locationToken, nested, offsetInChunk, pi, plusToken, popped, regex, rparen, strOffset, tag, token, tokens, value, _i, _len, _ref2, _ref3, _ref4;
if (options == null) {
options = {};
}
heredoc = options.heredoc, regex = options.regex, offsetInChunk = options.offsetInChunk, strOffset = options.strOffset, lexedLength = options.lexedLength;
offsetInChunk = offsetInChunk || 0;
strOffset = strOffset || 0;
lexedLength = lexedLength || str.length;
if (heredoc && str.length > 0 && str[0] === '\n') {
str = str.slice(1);
strOffset++;
}
offsetInChunk || (offsetInChunk = 0);
strOffset || (strOffset = 0);
lexedLength || (lexedLength = str.length);
tokens = [];
pi = 0;
i = -1;
@ -612,6 +620,9 @@
if (pi < i) {
tokens.push(this.makeToken('NEOSTRING', str.slice(pi, i), strOffset + pi));
}
if (!errorToken) {
errorToken = this.makeToken('', 'string interpolation', offsetInChunk + i + 1, 2);
}
inner = expr.slice(1, -1);
if (inner.length) {
_ref2 = this.getLineAndColumnFromChunk(strOffset + i + 1), line = _ref2[0], column = _ref2[1];
@ -648,7 +659,7 @@
tokens.unshift(this.makeToken('NEOSTRING', '', offsetInChunk));
}
if (interpolated = tokens.length > 1) {
this.token('(', '(', offsetInChunk, 0);
this.token('(', '(', offsetInChunk, 0, errorToken);
}
for (i = _i = 0, _len = tokens.length; _i < _len; i = ++_i) {
token = tokens[i];
@ -684,13 +695,12 @@
};
Lexer.prototype.pair = function(tag) {
var size, wanted;
var wanted;
if (tag !== (wanted = last(this.ends))) {
if ('OUTDENT' !== wanted) {
this.error("unmatched " + tag);
}
this.indent -= size = last(this.indents);
this.outdentToken(size, true);
this.outdentToken(last(this.indents), true);
return this.pair(tag);
}
return this.ends.pop();
@ -733,9 +743,12 @@
return token;
};
Lexer.prototype.token = function(tag, value, offsetInChunk, length) {
Lexer.prototype.token = function(tag, value, offsetInChunk, length, origin) {
var token;
token = this.makeToken(tag, value, offsetInChunk, length);
if (origin) {
token.origin = origin;
}
this.tokens.push(token);
return token;
};
@ -752,19 +765,34 @@
Lexer.prototype.unfinished = function() {
var _ref2;
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
};
Lexer.prototype.removeNewlines = function(str) {
return str.replace(/^\s*\n\s*/, '').replace(/([^\\]|\\\\)\s*\n\s*$/, '$1');
};
Lexer.prototype.escapeLines = function(str, heredoc) {
return str.replace(MULTILINER, heredoc ? '\\n' : '');
str = str.replace(/\\[^\S\n]*(\n|\\)\s*/g, function(escaped, character) {
if (character === '\n') {
return '';
} else {
return escaped;
}
});
if (heredoc) {
return str.replace(MULTILINER, '\\n');
} else {
return str.replace(/\s*\n\s*/g, ' ');
}
};
Lexer.prototype.makeString = function(body, quote, heredoc) {
if (!body) {
return quote + quote;
}
body = body.replace(/\\([\s\S])/g, function(match, contents) {
if (contents === '\n' || contents === quote) {
body = body.replace(RegExp("\\\\(" + quote + "|\\\\)", "g"), function(match, contents) {
if (contents === quote) {
return contents;
} else {
return match;
@ -774,10 +802,15 @@
return quote + this.escapeLines(body, heredoc) + quote;
};
Lexer.prototype.error = function(message) {
Lexer.prototype.error = function(message, offset) {
var first_column, first_line, _ref2;
if (offset == null) {
offset = 0;
}
_ref2 = this.getLineAndColumnFromChunk(offset), first_line = _ref2[0], first_column = _ref2[1];
return throwSyntaxError(message, {
first_line: this.chunkLine,
first_column: this.chunkColumn
first_line: first_line,
first_column: first_column
});
};
@ -828,27 +861,27 @@
NUMBER = /^0b[01]+|^0o[0-7]+|^0x[\da-f]+|^\d*\.?\d+(?:e[+-]?\d+)?/i;
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[^\n\S]*)?\1/;
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?(\.|::)|\.{2,3})/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
WHITESPACE = /^[^\n\S]+/;
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|(?:###)$)|^(?:\s*#(?!##[^#]).*)+/;
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
CODE = /^[-=]>/;
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
SIMPLESTR = /^'[^\\']*(?:\\.[^\\']*)*'/;
SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
HEREGEX = /^\/{3}([\s\S]+?)\/{3}([imgy]{0,4})(?!\w)/;
HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
HEREGEX_OMIT = /\s+(?:#.*)?/g;
HEREGEX_OMIT = /((?:\\\\)+)|\\(\s|\/)|\s+(?:#.*)?/g;
MULTILINER = /\n/g;
@ -860,9 +893,11 @@
TRAILING_SPACES = /\s+$/;
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%='];
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO'];
UNARY_MATH = ['!', '~'];
LOGIC = ['&&', '||', '&', '|', '^'];
@ -870,7 +905,7 @@
COMPARE = ['==', '!=', '<', '>', '<=', '>='];
MATH = ['*', '/', '%'];
MATH = ['*', '/', '%', '//', '%%'];
RELATION = ['IN', 'OF', 'INSTANCEOF'];
@ -886,4 +921,6 @@
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
INDENTABLE_CLOSERS = [')', '}', ']'];
}).call(this);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var LONG_FLAG, MULTI_FLAG, OPTIONAL, OptionParser, SHORT_FLAG, buildRule, buildRules, normalizeArguments, repeat;

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,66 @@
// Generated by CoffeeScript 1.7.1
(function() {
var CoffeeScript, Module, binary, child_process, ext, findExtension, fork, helpers, loadFile, path, _i, _len, _ref;
CoffeeScript = require('./coffee-script');
child_process = require('child_process');
helpers = require('./helpers');
path = require('path');
loadFile = function(module, filename) {
var answer;
answer = CoffeeScript._compileFile(filename, false);
return module._compile(answer, filename);
};
if (require.extensions) {
_ref = CoffeeScript.FILE_EXTENSIONS;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
ext = _ref[_i];
require.extensions[ext] = loadFile;
}
Module = require('module');
findExtension = function(filename) {
var curExtension, extensions;
extensions = path.basename(filename).split('.');
if (extensions[0] === '') {
extensions.shift();
}
while (extensions.shift()) {
curExtension = '.' + extensions.join('.');
if (Module._extensions[curExtension]) {
return curExtension;
}
}
return '.js';
};
Module.prototype.load = function(filename) {
var extension;
this.filename = filename;
this.paths = Module._nodeModulePaths(path.dirname(filename));
extension = findExtension(filename);
Module._extensions[extension](this, filename);
return this.loaded = true;
};
}
if (child_process) {
fork = child_process.fork;
binary = require.resolve('../../bin/coffee');
child_process.fork = function(path, args, options) {
if (helpers.isCoffee(path)) {
if (!Array.isArray(args)) {
options = args || {};
args = [];
}
args = [path].concat(args);
path = binary;
}
return fork(path, args, options);
};
}
}).call(this);

View File

@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var CoffeeScript, addHistory, addMultilineHandler, fs, merge, nodeREPL, path, prettyErrorMessage, replDefaults, vm, _ref;
var CoffeeScript, addHistory, addMultilineHandler, fs, merge, nodeREPL, path, replDefaults, updateSyntaxError, vm, _ref;
fs = require('fs');
@ -12,14 +12,14 @@
CoffeeScript = require('./coffee-script');
_ref = require('./helpers'), merge = _ref.merge, prettyErrorMessage = _ref.prettyErrorMessage;
_ref = require('./helpers'), merge = _ref.merge, updateSyntaxError = _ref.updateSyntaxError;
replDefaults = {
prompt: 'coffee> ',
historyFile: process.env.HOME ? path.join(process.env.HOME, '.coffee_history') : void 0,
historyMaxInputSize: 10240,
"eval": function(input, context, filename, cb) {
var Assign, Block, Literal, Value, ast, err, js, _ref1;
var Assign, Block, Literal, Value, ast, err, js, result, _ref1;
input = input.replace(/\uFF00/g, '\n');
input = input.replace(/^\(([\s\S]*)\n\)$/m, '$1');
_ref1 = require('./nodes'), Block = _ref1.Block, Assign = _ref1.Assign, Value = _ref1.Value, Literal = _ref1.Literal;
@ -30,10 +30,12 @@
bare: true,
locals: Object.keys(context)
});
return cb(null, vm.runInContext(js, context, filename));
result = context === global ? vm.runInThisContext(js, filename) : vm.runInContext(js, context, filename);
return cb(null, result);
} catch (_error) {
err = _error;
return cb(prettyErrorMessage(err, filename, input, true));
updateSyntaxError(err, input);
return cb(err);
}
}
};
@ -143,6 +145,8 @@
console.warn("Node 0.8.0+ required for CoffeeScript REPL");
process.exit(1);
}
CoffeeScript.register();
process.argv = ['coffee'].concat(process.argv.slice(2));
opts = merge(replDefaults, opts);
repl = nodeREPL.start(opts);
repl.on('exit', function() {

View File

@ -1,13 +1,16 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var BALANCED_PAIRS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _ref,
var BALANCED_PAIRS, CALL_CLOSERS, EXPRESSION_CLOSE, EXPRESSION_END, EXPRESSION_START, IMPLICIT_CALL, IMPLICIT_END, IMPLICIT_FUNC, IMPLICIT_UNSPACED_CALL, INVERSES, LINEBREAKS, SINGLE_CLOSERS, SINGLE_LINERS, generate, left, rite, _i, _len, _ref,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__slice = [].slice;
generate = function(tag, value) {
generate = function(tag, value, origin) {
var tok;
tok = [tag, value];
tok.generated = true;
if (origin) {
tok.origin = origin;
}
return tok;
};
@ -17,10 +20,9 @@
Rewriter.prototype.rewrite = function(tokens) {
this.tokens = tokens;
this.removeLeadingNewlines();
this.removeMidExpressionNewlines();
this.closeOpenCalls();
this.closeOpenIndexes();
this.addImplicitIndentation();
this.normalizeLines();
this.tagPostfixConditionals();
this.addImplicitBracesAndParens();
this.addLocationDataToGeneratedTokens();
@ -72,17 +74,6 @@
}
};
Rewriter.prototype.removeMidExpressionNewlines = function() {
return this.scanTokens(function(token, i, tokens) {
var _ref;
if (!(token[0] === 'TERMINATOR' && (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0))) {
return 1;
}
tokens.splice(i, 1);
return 0;
});
};
Rewriter.prototype.closeOpenCalls = function() {
var action, condition;
condition = function(token, i) {
@ -161,9 +152,9 @@
var stack;
stack = [];
return this.scanTokens(function(token, i, tokens) {
var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, nextTag, offset, prevTag, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
var endImplicitCall, endImplicitObject, forward, inImplicit, inImplicitCall, inImplicitControl, inImplicitObject, newLine, nextTag, offset, prevTag, prevToken, s, sameLine, stackIdx, stackTag, stackTop, startIdx, startImplicitCall, startImplicitObject, startsLine, tag, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
tag = token[0];
prevTag = (i > 0 ? tokens[i - 1] : [])[0];
prevTag = (prevToken = i > 0 ? tokens[i - 1] : [])[0];
nextTag = (i < tokens.length - 1 ? tokens[i + 1] : [])[0];
stackTop = function() {
return stack[stack.length - 1];
@ -219,7 +210,7 @@
ours: true
}
]);
tokens.splice(idx, 0, generate('{', generate(new String('{'))));
tokens.splice(idx, 0, generate('{', generate(new String('{')), token));
if (j == null) {
return i += 1;
}
@ -227,7 +218,7 @@
endImplicitObject = function(j) {
j = j != null ? j : i;
stack.pop();
tokens.splice(j, 0, generate('}', '}'));
tokens.splice(j, 0, generate('}', '}', token));
return i += 1;
};
if (inImplicitCall() && (tag === 'IF' || tag === 'TRY' || tag === 'FINALLY' || tag === 'CATCH' || tag === 'CLASS' || tag === 'SWITCH')) {
@ -287,6 +278,7 @@
while (this.tag(s - 2) === 'HERECOMMENT') {
s -= 2;
}
this.insideForDeclaration = nextTag === 'FOR';
startsLine = s === 0 || (_ref2 = this.tag(s - 1), __indexOf.call(LINEBREAKS, _ref2) >= 0) || tokens[s - 1].newLine;
if (stackTop()) {
_ref3 = stackTop(), stackTag = _ref3[0], stackIdx = _ref3[1];
@ -297,20 +289,17 @@
startImplicitObject(s, !!startsLine);
return forward(2);
}
if (prevTag === 'OUTDENT' && inImplicitCall() && (tag === '.' || tag === '?.' || tag === '::' || tag === '?::')) {
endImplicitCall();
return forward(1);
}
if (inImplicitObject() && __indexOf.call(LINEBREAKS, tag) >= 0) {
stackTop()[2].sameLine = false;
}
if (__indexOf.call(IMPLICIT_END, tag) >= 0) {
newLine = prevTag === 'OUTDENT' || prevToken.newLine;
if (__indexOf.call(IMPLICIT_END, tag) >= 0 || __indexOf.call(CALL_CLOSERS, tag) >= 0 && newLine) {
while (inImplicit()) {
_ref4 = stackTop(), stackTag = _ref4[0], stackIdx = _ref4[1], (_ref5 = _ref4[2], sameLine = _ref5.sameLine, startsLine = _ref5.startsLine);
if (inImplicitCall() && prevTag !== ',') {
endImplicitCall();
} else if (inImplicitObject() && sameLine && !startsLine) {
endImplicitObject();
} else if (inImplicitObject() && !this.insideForDeclaration && sameLine && tag !== 'TERMINATOR' && prevTag !== ':' && endImplicitObject()) {
} else if (inImplicitObject() && tag === 'TERMINATOR' && prevTag !== ',' && !(startsLine && this.looksObjectish(i + 1))) {
endImplicitObject();
} else {
@ -318,7 +307,7 @@
}
}
}
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
if (tag === ',' && !this.looksObjectish(i + 1) && inImplicitObject() && !this.insideForDeclaration && (nextTag !== 'TERMINATOR' || !this.looksObjectish(i + 2))) {
offset = nextTag === 'OUTDENT' ? 1 : 0;
while (inImplicitObject()) {
endImplicitObject(i + offset);
@ -354,30 +343,32 @@
});
};
Rewriter.prototype.addImplicitIndentation = function() {
Rewriter.prototype.normalizeLines = function() {
var action, condition, indent, outdent, starter;
starter = indent = outdent = null;
condition = function(token, i) {
var _ref, _ref1;
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref1 = token[0]) === 'CATCH' || _ref1 === 'FINALLY') && (starter === '->' || starter === '=>'));
var _ref, _ref1, _ref2, _ref3;
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'TERMINATOR' && (_ref1 = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref2 = token[0]) === 'CATCH' || _ref2 === 'FINALLY') && (starter === '->' || starter === '=>')) || (_ref3 = token[0], __indexOf.call(CALL_CLOSERS, _ref3) >= 0) && this.tokens[i - 1].newLine;
};
action = function(token, i) {
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
};
return this.scanTokens(function(token, i, tokens) {
var j, tag, _i, _ref, _ref1;
var j, tag, _i, _ref, _ref1, _ref2;
tag = token[0];
if (tag === 'TERMINATOR' && this.tag(i + 1) === 'THEN') {
tokens.splice(i, 1);
return 0;
}
if (tag === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
tokens.splice.apply(tokens, [i, 0].concat(__slice.call(this.indentation())));
return 2;
if (tag === 'TERMINATOR') {
if (this.tag(i + 1) === 'ELSE' && this.tag(i - 1) !== 'OUTDENT') {
tokens.splice.apply(tokens, [i, 1].concat(__slice.call(this.indentation())));
return 1;
}
if (_ref = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0) {
tokens.splice(i, 1);
return 0;
}
}
if (tag === 'CATCH') {
for (j = _i = 1; _i <= 2; j = ++_i) {
if (!((_ref = this.tag(i + j)) === 'OUTDENT' || _ref === 'TERMINATOR' || _ref === 'FINALLY')) {
if (!((_ref1 = this.tag(i + j)) === 'OUTDENT' || _ref1 === 'TERMINATOR' || _ref1 === 'FINALLY')) {
continue;
}
tokens.splice.apply(tokens, [i + j, 0].concat(__slice.call(this.indentation())));
@ -386,7 +377,7 @@
}
if (__indexOf.call(SINGLE_LINERS, tag) >= 0 && this.tag(i + 1) !== 'INDENT' && !(tag === 'ELSE' && this.tag(i + 1) === 'IF')) {
starter = tag;
_ref1 = this.indentation(true), indent = _ref1[0], outdent = _ref1[1];
_ref2 = this.indentation(tokens[i]), indent = _ref2[0], outdent = _ref2[1];
if (starter === 'THEN') {
indent.fromThen = true;
}
@ -425,17 +416,14 @@
});
};
Rewriter.prototype.indentation = function(implicit) {
Rewriter.prototype.indentation = function(origin) {
var indent, outdent;
if (implicit == null) {
implicit = false;
}
indent = ['INDENT', 2];
outdent = ['OUTDENT', 2];
if (implicit) {
if (origin) {
indent.generated = outdent.generated = true;
}
if (!implicit) {
indent.origin = outdent.origin = origin;
} else {
indent.explicit = outdent.explicit = true;
}
return [indent, outdent];
@ -466,11 +454,11 @@
EXPRESSION_END.push(INVERSES[left] = rite);
}
EXPRESSION_CLOSE = ['CATCH', 'WHEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
EXPRESSION_CLOSE = ['CATCH', 'THEN', 'ELSE', 'FINALLY'].concat(EXPRESSION_END);
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
IMPLICIT_UNSPACED_CALL = ['+', '-'];
@ -482,4 +470,6 @@
LINEBREAKS = ['TERMINATOR', 'INDENT', 'OUTDENT'];
CALL_CLOSERS = ['.', '?.', '::', '?::'];
}).call(this);

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var Scope, extend, last, _ref;

View File

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.6.3
// Generated by CoffeeScript 1.7.1
(function() {
var LineMap, SourceMap;

View File

@ -0,0 +1,2 @@
node_modules/
npm-debug.log

View File

@ -0,0 +1,5 @@
language: node_js
node_js:
- 0.6
- 0.8
- 0.9

View File

@ -0,0 +1,21 @@
Copyright 2010 James Halliday (mail@substack.net)
This project is free software released under the MIT/X11 license:
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,6 @@
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', function (err) {
if (err) console.error(err)
else console.log('pow!')
});

View File

@ -0,0 +1,82 @@
var path = require('path');
var fs = require('fs');
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
function mkdirP (p, mode, f, made) {
if (typeof mode === 'function' || mode === undefined) {
f = mode;
mode = 0777 & (~process.umask());
}
if (!made) made = null;
var cb = f || function () {};
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
fs.mkdir(p, mode, function (er) {
if (!er) {
made = made || p;
return cb(null, made);
}
switch (er.code) {
case 'ENOENT':
mkdirP(path.dirname(p), mode, function (er, made) {
if (er) cb(er, made);
else mkdirP(p, mode, cb, made);
});
break;
// In the case of any other error, just see if there's a dir
// there already. If so, then hooray! If not, then something
// is borked.
default:
fs.stat(p, function (er2, stat) {
// if the stat fails, then that's super weird.
// let the original error be the failure reason.
if (er2 || !stat.isDirectory()) cb(er, made)
else cb(null, made);
});
break;
}
});
}
mkdirP.sync = function sync (p, mode, made) {
if (mode === undefined) {
mode = 0777 & (~process.umask());
}
if (!made) made = null;
if (typeof mode === 'string') mode = parseInt(mode, 8);
p = path.resolve(p);
try {
fs.mkdirSync(p, mode);
made = made || p;
}
catch (err0) {
switch (err0.code) {
case 'ENOENT' :
made = sync(path.dirname(p), mode, made);
sync(p, mode, made);
break;
// In the case of any other error, just see if there's a dir
// there already. If so, then hooray! If not, then something
// is borked.
default:
var stat;
try {
stat = fs.statSync(p);
}
catch (err1) {
throw err0;
}
if (!stat.isDirectory()) throw err0;
break;
}
}
return made;
};

View File

@ -0,0 +1,38 @@
{
"name": "mkdirp",
"description": "Recursively mkdir, like `mkdir -p`",
"version": "0.3.5",
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"main": "./index",
"keywords": [
"mkdir",
"directory"
],
"repository": {
"type": "git",
"url": "http://github.com/substack/node-mkdirp.git"
},
"scripts": {
"test": "tap test/*.js"
},
"devDependencies": {
"tap": "~0.4.0"
},
"license": "MIT",
"readme": "# mkdirp\n\nLike `mkdir -p`, but in node.js!\n\n[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)\n\n# example\n\n## pow.js\n\n```js\nvar mkdirp = require('mkdirp');\n \nmkdirp('/tmp/foo/bar/baz', function (err) {\n if (err) console.error(err)\n else console.log('pow!')\n});\n```\n\nOutput\n\n```\npow!\n```\n\nAnd now /tmp/foo/bar/baz exists, huzzah!\n\n# methods\n\n```js\nvar mkdirp = require('mkdirp');\n```\n\n## mkdirp(dir, mode, cb)\n\nCreate a new directory and any necessary subdirectories at `dir` with octal\npermission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\n`cb(err, made)` fires with the error or the first directory `made`\nthat had to be created, if any.\n\n## mkdirp.sync(dir, mode)\n\nSynchronously create a new directory and any necessary subdirectories at `dir`\nwith octal permission string `mode`.\n\nIf `mode` isn't specified, it defaults to `0777 & (~process.umask())`.\n\nReturns the first directory that had to be created, if any.\n\n# install\n\nWith [npm](http://npmjs.org) do:\n\n```\nnpm install mkdirp\n```\n\n# license\n\nMIT\n",
"readmeFilename": "readme.markdown",
"bugs": {
"url": "https://github.com/substack/node-mkdirp/issues"
},
"homepage": "https://github.com/substack/node-mkdirp",
"_id": "mkdirp@0.3.5",
"dist": {
"shasum": "3ca8fc91ed924e281236eec99e74505873ac5a45"
},
"_from": "mkdirp@~0.3.5",
"_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
}

View File

@ -0,0 +1,63 @@
# mkdirp
Like `mkdir -p`, but in node.js!
[![build status](https://secure.travis-ci.org/substack/node-mkdirp.png)](http://travis-ci.org/substack/node-mkdirp)
# example
## pow.js
```js
var mkdirp = require('mkdirp');
mkdirp('/tmp/foo/bar/baz', function (err) {
if (err) console.error(err)
else console.log('pow!')
});
```
Output
```
pow!
```
And now /tmp/foo/bar/baz exists, huzzah!
# methods
```js
var mkdirp = require('mkdirp');
```
## mkdirp(dir, mode, cb)
Create a new directory and any necessary subdirectories at `dir` with octal
permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
`cb(err, made)` fires with the error or the first directory `made`
that had to be created, if any.
## mkdirp.sync(dir, mode)
Synchronously create a new directory and any necessary subdirectories at `dir`
with octal permission string `mode`.
If `mode` isn't specified, it defaults to `0777 & (~process.umask())`.
Returns the first directory that had to be created, if any.
# install
With [npm](http://npmjs.org) do:
```
npm install mkdirp
```
# license
MIT

View File

@ -0,0 +1,38 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
test('chmod-pre', function (t) {
var mode = 0744
mkdirp(file, mode, function (er) {
t.ifError(er, 'should not error');
fs.stat(file, function (er, stat) {
t.ifError(er, 'should exist');
t.ok(stat && stat.isDirectory(), 'should be directory');
t.equal(stat && stat.mode & 0777, mode, 'should be 0744');
t.end();
});
});
});
test('chmod', function (t) {
var mode = 0755
mkdirp(file, mode, function (er) {
t.ifError(er, 'should not error');
fs.stat(file, function (er, stat) {
t.ifError(er, 'should exist');
t.ok(stat && stat.isDirectory(), 'should be directory');
t.end();
});
});
});

View File

@ -0,0 +1,37 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
// a file in the way
var itw = ps.slice(0, 3).join('/');
test('clobber-pre', function (t) {
console.error("about to write to "+itw)
fs.writeFileSync(itw, 'I AM IN THE WAY, THE TRUTH, AND THE LIGHT.');
fs.stat(itw, function (er, stat) {
t.ifError(er)
t.ok(stat && stat.isFile(), 'should be file')
t.end()
})
})
test('clobber', function (t) {
t.plan(2);
mkdirp(file, 0755, function (err) {
t.ok(err);
t.equal(err.code, 'ENOTDIR');
t.end();
});
});

View File

@ -0,0 +1,28 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('woo', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

View File

@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('async perm', function (t) {
t.plan(2);
var file = '/tmp/' + (Math.random() * (1<<30)).toString(16);
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});
test('async root perm', function (t) {
mkdirp('/tmp', 0755, function (err) {
if (err) t.fail(err);
t.end();
});
t.end();
});

View File

@ -0,0 +1,39 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('sync perm', function (t) {
t.plan(2);
var file = '/tmp/' + (Math.random() * (1<<30)).toString(16) + '.json';
mkdirp.sync(file, 0755);
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
});
});
test('sync root perm', function (t) {
t.plan(1);
var file = '/tmp';
mkdirp.sync(file, 0755);
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
});
});

View File

@ -0,0 +1,41 @@
var mkdirp = require('../').mkdirp;
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('race', function (t) {
t.plan(4);
var ps = [ '', 'tmp' ];
for (var i = 0; i < 25; i++) {
var dir = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
ps.push(dir);
}
var file = ps.join('/');
var res = 2;
mk(file, function () {
if (--res === 0) t.end();
});
mk(file, function () {
if (--res === 0) t.end();
});
function mk (file, cb) {
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
if (cb) cb();
}
})
})
});
}
});

View File

@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('rel', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var cwd = process.cwd();
process.chdir('/tmp');
var file = [x,y,z].join('/');
mkdirp(file, 0755, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
process.chdir(cwd);
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

View File

@ -0,0 +1,25 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('return value', function (t) {
t.plan(4);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
// should return the first dir created.
// By this point, it would be profoundly surprising if /tmp didn't
// already exist, since every other test makes things in there.
mkdirp(file, function (err, made) {
t.ifError(err);
t.equal(made, '/tmp/' + x);
mkdirp(file, function (err, made) {
t.ifError(err);
t.equal(made, null);
});
});
});

View File

@ -0,0 +1,24 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('return value', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
// should return the first dir created.
// By this point, it would be profoundly surprising if /tmp didn't
// already exist, since every other test makes things in there.
// Note that this will throw on failure, which will fail the test.
var made = mkdirp.sync(file);
t.equal(made, '/tmp/' + x);
// making the same file again should have no effect.
made = mkdirp.sync(file);
t.equal(made, null);
});

View File

@ -0,0 +1,18 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('root', function (t) {
// '/' on unix, 'c:/' on windows.
var file = path.resolve('/');
mkdirp(file, 0755, function (err) {
if (err) throw err
fs.stat(file, function (er, stat) {
if (er) throw er
t.ok(stat.isDirectory(), 'target is a directory');
t.end();
})
});
});

View File

@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('sync', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
try {
mkdirp.sync(file, 0755);
} catch (err) {
t.fail(err);
return t.end();
}
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0755);
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
});
});
});

View File

@ -0,0 +1,28 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('implicit mode from umask', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
mkdirp(file, function (err) {
if (err) t.fail(err);
else path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, 0777 & (~process.umask()));
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
})
})
});
});

View File

@ -0,0 +1,32 @@
var mkdirp = require('../');
var path = require('path');
var fs = require('fs');
var test = require('tap').test;
test('umask sync modes', function (t) {
t.plan(2);
var x = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var y = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var z = Math.floor(Math.random() * Math.pow(16,4)).toString(16);
var file = '/tmp/' + [x,y,z].join('/');
try {
mkdirp.sync(file);
} catch (err) {
t.fail(err);
return t.end();
}
path.exists(file, function (ex) {
if (!ex) t.fail('file not created')
else fs.stat(file, function (err, stat) {
if (err) t.fail(err)
else {
t.equal(stat.mode & 0777, (0777 & (~process.umask())));
t.ok(stat.isDirectory(), 'target not a directory');
t.end();
}
});
});
});

View File

@ -10,13 +10,8 @@
"author": {
"name": "Jeremy Ashkenas"
},
"version": "1.6.3",
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/jashkenas/coffee-script/master/LICENSE"
}
],
"version": "1.7.1",
"license": "MIT",
"engines": {
"node": ">=0.8.0"
},
@ -41,14 +36,19 @@
},
"devDependencies": {
"uglify-js": "~2.2",
"jison": ">=0.2.0"
"jison": ">=0.2.0",
"highlight.js": "~8.0.0",
"underscore": "~1.5.2"
},
"readme": "\n {\n } } {\n { { } }\n } }{ {\n { }{ } } _____ __ __\n ( }{ }{ { ) / ____| / _|/ _|\n .- { { } { }} -. | | ___ | |_| |_ ___ ___\n ( ( } { } { } } ) | | / _ \\| _| _/ _ \\/ _ \\\n |`-..________ ..-'| | |___| (_) | | | || __/ __/\n | | \\_____\\___/|_| |_| \\___|\\___|\n | ;--.\n | (__ \\ _____ _ _\n | | ) ) / ____| (_) | |\n | |/ / | (___ ___ _ __ _ _ __ | |_\n | ( / \\___ \\ / __| '__| | '_ \\| __|\n | |/ ____) | (__| | | | |_) | |_\n | | |_____/ \\___|_| |_| .__/ \\__|\n `-.._________..-' | |\n |_|\n\n\n CoffeeScript is a little language that compiles into JavaScript.\n\n Install Node.js, and then the CoffeeScript compiler:\n sudo bin/cake install\n\n Or, if you have the Node Package Manager installed:\n npm install -g coffee-script\n (Leave off the -g if you don't wish to install globally.)\n\n Execute a script:\n coffee /path/to/script.coffee\n\n Compile a script:\n coffee -c /path/to/script.coffee\n\n For documentation, usage, and examples, see:\n http://coffeescript.org/\n\n To suggest a feature, report a bug, or general discussion:\n http://github.com/jashkenas/coffee-script/issues/\n\n If you'd like to chat, drop by #coffeescript on Freenode IRC,\n or on webchat.freenode.net.\n\n The source repository:\n git://github.com/jashkenas/coffee-script.git\n\n All contributors are listed here:\n http://github.com/jashkenas/coffee-script/contributors\n",
"dependencies": {
"mkdirp": "~0.3.5"
},
"readme": " {\n } } {\n { { } }\n } }{ {\n { }{ } } _____ __ __\n { }{ }{ { } / ____| / _|/ _|\n .- { { } { }} -. | | ___ | |_| |_ ___ ___\n ( { } { } { } } ) | | / _ \\| _| _/ _ \\/ _ \\\n |`-..________ ..-'| | |___| (_) | | | || __/ __/\n | | \\_____\\___/|_| |_| \\___|\\___|\n | ;--.\n | (__ \\ _____ _ _\n | | ) ) / ____| (_) | |\n | |/ / | (___ ___ _ __ _ _ __ | |_\n | ( / \\___ \\ / __| '__| | '_ \\| __|\n | |/ ____) | (__| | | | |_) | |_\n | | |_____/ \\___|_| |_| .__/ \\__|\n `-.._________..-' | |\n |_|\n\n\n CoffeeScript is a little language that compiles into JavaScript.\n\n If you have the Node Package Manager installed:\n npm install -g coffee-script\n (Leave off the -g if you don't wish to install globally.)\n\n Or, if you don't wish to use npm:\n sudo bin/cake install\n\n Execute a script:\n coffee /path/to/script.coffee\n\n Compile a script:\n coffee -c /path/to/script.coffee\n\n For documentation, usage, and examples, see:\n http://coffeescript.org/\n\n To suggest a feature, report a bug, or general discussion:\n http://github.com/jashkenas/coffee-script/issues/\n\n If you'd like to chat, drop by #coffeescript on Freenode IRC,\n or on webchat.freenode.net.\n\n The source repository:\n git://github.com/jashkenas/coffee-script.git\n\n Top 100 contributors are listed here:\n http://github.com/jashkenas/coffee-script/contributors\n",
"readmeFilename": "README",
"_id": "coffee-script@1.6.3",
"_id": "coffee-script@1.7.1",
"dist": {
"shasum": "6355d32cf1b04cdff6b484e5e711782b2f0c39be"
"shasum": "aee704e24729dcd3e46efea4874f8eaf2ad7eaf6"
},
"_from": "coffee-script@1.6.3",
"_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz"
"_from": "coffee-script@1.7.1",
"_resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz"
}

1
js/npm/node_modules/coffee-script/register.js generated vendored Normal file
View File

@ -0,0 +1 @@
require('./lib/coffee-script/register');

View File

@ -10,6 +10,10 @@ via [npm (node package manager)](http://github.com/isaacs/npm)
$ npm install sinon
via [NuGet (package manager for Microsoft development platform)](https://www.nuget.org/packages/SinonJS)
Install-Package SinonJS
or install via git by cloning the repository and including sinon.js
in your project, as you would any other third party library.
@ -50,10 +54,13 @@ Node installed, and install Sinon's dependencies:
### In the browser
Open `test/sinon.html` in a browser. To test against a built distribution, first
make sure you have a build (requires Ruby and Juicer):
make sure you have a build (requires [Ruby][ruby] and [Juicer][juicer]):
$ ./build
[ruby]: https://www.ruby-lang.org/en/
[juicer]: http://rubygems.org/gems/juicer
Then open `test/sinon-dist.html` in a browser.
If the build script is unable to find Juicer, try

View File

@ -10,7 +10,7 @@
*/
"use strict";
var sinon = (function (buster) {
var sinon = (function (formatio) {
var div = typeof document != "undefined" && document.createElement("div");
var hasOwn = Object.prototype.hasOwnProperty;
@ -63,26 +63,38 @@ var sinon = (function (buster) {
throw new TypeError("Method wrapper should be function");
}
var wrappedMethod = object[property];
var wrappedMethod = object[property],
error;
if (!isFunction(wrappedMethod)) {
throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
property + " as function");
}
if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
}
if (wrappedMethod.calledBefore) {
var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
}
// IE 8 does not support hasOwnProperty on the window object.
var owned = hasOwn.call(object, property);
if (error) {
if (wrappedMethod._stack) {
error.stack += '\n--------------\n' + wrappedMethod._stack;
}
throw error;
}
// IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
// when using hasOwn.call on objects from other frames.
var owned = object.hasOwnProperty ? object.hasOwnProperty(property) : hasOwn.call(object, property);
object[property] = method;
method.displayName = property;
// Set up a stack trace which can be used later to find what line of
// code the original method was created on.
method._stack = (new Error('Stack Trace for original')).stack;
method.restore = function () {
// For prototype properties try to reset by delete first.
@ -151,26 +163,16 @@ var sinon = (function (buster) {
return false;
}
if (aString == "[object Array]") {
if (a.length !== b.length) {
return false;
}
for (var i = 0, l = a.length; i < l; i += 1) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
if (aString == "[object Date]") {
return a.valueOf() === b.valueOf();
}
var prop, aLength = 0, bLength = 0;
if (aString == "[object Array]" && a.length !== b.length) {
return false;
}
for (prop in a) {
aLength += 1;
@ -277,7 +279,7 @@ var sinon = (function (buster) {
log: function () {},
logError: function (label, err) {
var msg = label + " threw exception: "
var msg = label + " threw exception: ";
sinon.log(msg + "[" + err.name + "] " + err.message);
if (err.stack) { sinon.log(err.stack); }
@ -319,14 +321,21 @@ var sinon = (function (buster) {
}
};
var isNode = typeof module == "object" && typeof require == "function";
var isNode = typeof module !== "undefined" && module.exports;
var isAMD = typeof define === 'function' && typeof define.amd === 'object' && define.amd;
if (isNode) {
if (isAMD) {
define(function(){
return sinon;
});
} else if (isNode) {
try {
buster = { format: require("buster-format") };
formatio = require("formatio");
} catch (e) {}
module.exports = sinon;
module.exports.spy = require("./sinon/spy");
module.exports.spyCall = require("./sinon/call");
module.exports.behavior = require("./sinon/behavior");
module.exports.stub = require("./sinon/stub");
module.exports.mock = require("./sinon/mock");
module.exports.collection = require("./sinon/collection");
@ -338,9 +347,8 @@ var sinon = (function (buster) {
module.exports.match = require("./sinon/match");
}
if (buster) {
var formatter = sinon.create(buster.format);
formatter.quoteStrings = false;
if (formatio) {
var formatter = formatio.configure({ quoteStrings: false });
sinon.format = function () {
return formatter.ascii.apply(formatter, arguments);
};
@ -357,4 +365,4 @@ var sinon = (function (buster) {
}
return sinon;
}(typeof buster == "object" && buster));
}(typeof formatio == "object" && formatio));

View File

@ -15,7 +15,7 @@
"use strict";
(function (sinon, global) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== "undefined" && module.exports;
var slice = Array.prototype.slice;
var assert;
@ -83,7 +83,7 @@
function exposedName(prefix, prop) {
return !prefix || /^fail/.test(prop) ? prop :
prefix + prop.slice(0, 1).toUpperCase() + prop.slice(1);
};
}
assert = {
failException: "AssertError",

332
js/npm/node_modules/sinon/lib/sinon/behavior.js generated vendored Normal file
View File

@ -0,0 +1,332 @@
/**
* @depend ../sinon.js
*/
/*jslint eqeqeq: false, onevar: false*/
/*global module, require, sinon, process, setImmediate, setTimeout*/
/**
* Stub behavior
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Tim Fischbach (mail@timfischbach.de)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
"use strict";
(function (sinon) {
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
}
if (!sinon) {
return;
}
var slice = Array.prototype.slice;
var join = Array.prototype.join;
var proto;
var nextTick = (function () {
if (typeof process === "object" && typeof process.nextTick === "function") {
return process.nextTick;
} else if (typeof setImmediate === "function") {
return setImmediate;
} else {
return function (callback) {
setTimeout(callback, 0);
};
}
})();
function throwsException(error, message) {
if (typeof error == "string") {
this.exception = new Error(message || "");
this.exception.name = error;
} else if (!error) {
this.exception = new Error("Error");
} else {
this.exception = error;
}
return this;
}
function getCallback(behavior, args) {
var callArgAt = behavior.callArgAt;
if (callArgAt < 0) {
var callArgProp = behavior.callArgProp;
for (var i = 0, l = args.length; i < l; ++i) {
if (!callArgProp && typeof args[i] == "function") {
return args[i];
}
if (callArgProp && args[i] &&
typeof args[i][callArgProp] == "function") {
return args[i][callArgProp];
}
}
return null;
}
return args[callArgAt];
}
function getCallbackError(behavior, func, args) {
if (behavior.callArgAt < 0) {
var msg;
if (behavior.callArgProp) {
msg = sinon.functionName(behavior.stub) +
" expected to yield to '" + behavior.callArgProp +
"', but no object with such a property was passed.";
} else {
msg = sinon.functionName(behavior.stub) +
" expected to yield, but no callback was passed.";
}
if (args.length > 0) {
msg += " Received [" + join.call(args, ", ") + "]";
}
return msg;
}
return "argument at index " + behavior.callArgAt + " is not a function: " + func;
}
function callCallback(behavior, args) {
if (typeof behavior.callArgAt == "number") {
var func = getCallback(behavior, args);
if (typeof func != "function") {
throw new TypeError(getCallbackError(behavior, func, args));
}
if (behavior.callbackAsync) {
nextTick(function() {
func.apply(behavior.callbackContext, behavior.callbackArguments);
});
} else {
func.apply(behavior.callbackContext, behavior.callbackArguments);
}
}
}
proto = {
create: function(stub) {
var behavior = sinon.extend({}, sinon.behavior);
delete behavior.create;
behavior.stub = stub;
return behavior;
},
isPresent: function() {
return (typeof this.callArgAt == 'number' ||
this.exception ||
typeof this.returnArgAt == 'number' ||
this.returnThis ||
this.returnValueDefined);
},
invoke: function(context, args) {
callCallback(this, args);
if (this.exception) {
throw this.exception;
} else if (typeof this.returnArgAt == 'number') {
return args[this.returnArgAt];
} else if (this.returnThis) {
return context;
}
return this.returnValue;
},
onCall: function(index) {
return this.stub.onCall(index);
},
onFirstCall: function() {
return this.stub.onFirstCall();
},
onSecondCall: function() {
return this.stub.onSecondCall();
},
onThirdCall: function() {
return this.stub.onThirdCall();
},
withArgs: function(/* arguments */) {
throw new Error('Defining a stub by invoking "stub.onCall(...).withArgs(...)" is not supported. ' +
'Use "stub.withArgs(...).onCall(...)" to define sequential behavior for calls with certain arguments.');
},
callsArg: function callsArg(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.callArgAt = pos;
this.callbackArguments = [];
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
callsArgOn: function callsArgOn(pos, context) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAt = pos;
this.callbackArguments = [];
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
callsArgWith: function callsArgWith(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.callArgAt = pos;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
callsArgOnWith: function callsArgWith(pos, context) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAt = pos;
this.callbackArguments = slice.call(arguments, 2);
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
yields: function () {
this.callArgAt = -1;
this.callbackArguments = slice.call(arguments, 0);
this.callbackContext = undefined;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
yieldsOn: function (context) {
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAt = -1;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = context;
this.callArgProp = undefined;
this.callbackAsync = false;
return this;
},
yieldsTo: function (prop) {
this.callArgAt = -1;
this.callbackArguments = slice.call(arguments, 1);
this.callbackContext = undefined;
this.callArgProp = prop;
this.callbackAsync = false;
return this;
},
yieldsToOn: function (prop, context) {
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAt = -1;
this.callbackArguments = slice.call(arguments, 2);
this.callbackContext = context;
this.callArgProp = prop;
this.callbackAsync = false;
return this;
},
"throws": throwsException,
throwsException: throwsException,
returns: function returns(value) {
this.returnValue = value;
this.returnValueDefined = true;
return this;
},
returnsArg: function returnsArg(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.returnArgAt = pos;
return this;
},
returnsThis: function returnsThis() {
this.returnThis = true;
return this;
}
};
// create asynchronous versions of callsArg* and yields* methods
for (var method in proto) {
// need to avoid creating anotherasync versions of the newly added async methods
if (proto.hasOwnProperty(method) &&
method.match(/^(callsArg|yields)/) &&
!method.match(/Async/)) {
proto[method + 'Async'] = (function (syncFnName) {
return function () {
var result = this[syncFnName].apply(this, arguments);
this.callbackAsync = true;
return result;
};
})(method);
}
}
if (commonJSModule) {
module.exports = proto;
} else {
sinon.behavior = proto;
}
}(typeof sinon == "object" && sinon || null));

View File

@ -17,7 +17,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
}
@ -90,7 +90,7 @@
return this.exception === error || this.exception.name === error;
},
calledWithNew: function calledWithNew(thisValue) {
calledWithNew: function calledWithNew() {
return this.thisValue instanceof this.proxy;
},
@ -191,7 +191,7 @@
proxyCall.callId = id;
return proxyCall;
};
}
createSpyCall.toString = callProto.toString; // used by mocks
if (commonJSModule) {

View File

@ -16,7 +16,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
var push = [].push;
var hasOwnProperty = Object.prototype.hasOwnProperty;

View File

@ -12,7 +12,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");

View File

@ -15,8 +15,9 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
var push = [].push;
var match;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
@ -26,6 +27,12 @@
return;
}
match = sinon.match;
if (!match && commonJSModule) {
match = require("./match");
}
function mock(object) {
if (!object) {
return sinon.expectation.create("Anonymous mock");
@ -206,6 +213,14 @@
return expectation.callCount == expectation.maxCalls;
}
function verifyMatcher(possibleMatcher, arg){
if (match && match.isMatcher(possibleMatcher)) {
return possibleMatcher.test(arg);
} else {
return true;
}
}
return {
minCalls: 1,
maxCalls: 1,
@ -315,6 +330,12 @@
}
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
if (!verifyMatcher(this.expectedArguments[i],args[i])) {
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
", didn't match " + this.expectedArguments.toString());
}
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
sinon.expectation.fail(this.method + " received wrong arguments " + sinon.format(args) +
", expected " + sinon.format(this.expectedArguments));
@ -347,6 +368,10 @@
}
for (var i = 0, l = this.expectedArguments.length; i < l; i += 1) {
if (!verifyMatcher(this.expectedArguments[i],args[i])) {
return false;
}
if (!sinon.deepEqual(this.expectedArguments[i], args[i])) {
return false;
}

View File

@ -17,7 +17,7 @@
*/
"use strict";
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
var sinon = require("../sinon");
sinon.extend(sinon, require("./util/fake_timers"));
}
@ -30,7 +30,7 @@ if (typeof module == "object" && typeof require == "function") {
return;
}
if (config.injectInto) {
if (config.injectInto && !(key in config.injectInto) ) {
config.injectInto[key] = value;
} else {
push.call(sandbox.args, value);
@ -119,7 +119,7 @@ if (typeof module == "object" && typeof require == "function") {
sinon.sandbox.useFakeXMLHttpRequest = sinon.sandbox.useFakeServer;
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon.sandbox;
}
}());

View File

@ -1,201 +1,6 @@
/**
* @depend ../sinon.js
* @depend match.js
*/
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
/*global module, require, sinon*/
/**
* Spy calls
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Maximilian Antoni (mail@maxantoni.de)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
* Copyright (c) 2013 Maximilian Antoni
*/
"use strict";
var commonJSModule = typeof module == "object" && typeof require == "function";
if (!this.sinon && commonJSModule) {
var sinon = require("../sinon");
}
(function (sinon) {
function throwYieldError(proxy, text, args) {
var msg = sinon.functionName(proxy) + text;
if (args.length) {
msg += " Received [" + slice.call(args).join(", ") + "]";
}
throw new Error(msg);
}
var slice = Array.prototype.slice;
var callProto = {
calledOn: function calledOn(thisValue) {
if (sinon.match && sinon.match.isMatcher(thisValue)) {
return thisValue.test(this.thisValue);
}
return this.thisValue === thisValue;
},
calledWith: function calledWith() {
for (var i = 0, l = arguments.length; i < l; i += 1) {
if (!sinon.deepEqual(arguments[i], this.args[i])) {
return false;
}
}
return true;
},
calledWithMatch: function calledWithMatch() {
for (var i = 0, l = arguments.length; i < l; i += 1) {
var actual = this.args[i];
var expectation = arguments[i];
if (!sinon.match || !sinon.match(expectation).test(actual)) {
return false;
}
}
return true;
},
calledWithExactly: function calledWithExactly() {
return arguments.length == this.args.length &&
this.calledWith.apply(this, arguments);
},
notCalledWith: function notCalledWith() {
return !this.calledWith.apply(this, arguments);
},
notCalledWithMatch: function notCalledWithMatch() {
return !this.calledWithMatch.apply(this, arguments);
},
returned: function returned(value) {
return sinon.deepEqual(value, this.returnValue);
},
threw: function threw(error) {
if (typeof error === "undefined" || !this.exception) {
return !!this.exception;
}
return this.exception === error || this.exception.name === error;
},
calledWithNew: function calledWithNew(thisValue) {
return this.thisValue instanceof this.proxy;
},
calledBefore: function (other) {
return this.callId < other.callId;
},
calledAfter: function (other) {
return this.callId > other.callId;
},
callArg: function (pos) {
this.args[pos]();
},
callArgOn: function (pos, thisValue) {
this.args[pos].apply(thisValue);
},
callArgWith: function (pos) {
this.callArgOnWith.apply(this, [pos, null].concat(slice.call(arguments, 1)));
},
callArgOnWith: function (pos, thisValue) {
var args = slice.call(arguments, 2);
this.args[pos].apply(thisValue, args);
},
"yield": function () {
this.yieldOn.apply(this, [null].concat(slice.call(arguments, 0)));
},
yieldOn: function (thisValue) {
var args = this.args;
for (var i = 0, l = args.length; i < l; ++i) {
if (typeof args[i] === "function") {
args[i].apply(thisValue, slice.call(arguments, 1));
return;
}
}
throwYieldError(this.proxy, " cannot yield since no callback was passed.", args);
},
yieldTo: function (prop) {
this.yieldToOn.apply(this, [prop, null].concat(slice.call(arguments, 1)));
},
yieldToOn: function (prop, thisValue) {
var args = this.args;
for (var i = 0, l = args.length; i < l; ++i) {
if (args[i] && typeof args[i][prop] === "function") {
args[i][prop].apply(thisValue, slice.call(arguments, 2));
return;
}
}
throwYieldError(this.proxy, " cannot yield to '" + prop +
"' since no callback was passed.", args);
},
toString: function () {
var callStr = this.proxy.toString() + "(";
var args = [];
for (var i = 0, l = this.args.length; i < l; ++i) {
args.push(sinon.format(this.args[i]));
}
callStr = callStr + args.join(", ") + ")";
if (typeof this.returnValue != "undefined") {
callStr += " => " + sinon.format(this.returnValue);
}
if (this.exception) {
callStr += " !" + this.exception.name;
if (this.exception.message) {
callStr += "(" + this.exception.message + ")";
}
}
return callStr;
}
};
callProto.invokeCallback = callProto.yield;
function createSpyCall(spy, thisValue, args, returnValue, exception, id) {
if (typeof id !== "number") {
throw new TypeError("Call id is not a number");
}
var proxyCall = sinon.create(callProto);
proxyCall.proxy = spy;
proxyCall.thisValue = thisValue;
proxyCall.args = args;
proxyCall.returnValue = returnValue;
proxyCall.exception = exception;
proxyCall.callId = id;
return proxyCall;
};
createSpyCall.toString = callProto.toString; // used by mocks
sinon.spyCall = createSpyCall;
}(typeof sinon == "object" && sinon || null));
/**
* @depend ../sinon.js
* @depend call.js
*/
/*jslint eqeqeq: false, onevar: false, plusplus: false*/
/*global module, require, sinon*/
@ -210,11 +15,19 @@ if (!this.sinon && commonJSModule) {
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
var push = Array.prototype.push;
var slice = Array.prototype.slice;
var callId = 0;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
}
if (!sinon) {
return;
}
function spy(object, property) {
if (!property && typeof object == "function") {
return spy.create(object);
@ -233,8 +46,6 @@ if (!this.sinon && commonJSModule) {
return;
}
var alen = args.length;
for (var i = 0, l = fakes.length; i < l; i++) {
if (fakes[i].matches(args, strict)) {
return fakes[i];
@ -341,18 +152,24 @@ if (!this.sinon && commonJSModule) {
} else {
returnValue = (this.func || func).apply(thisValue, args);
}
var thisCall = this.getCall(this.callCount - 1);
if (thisCall.calledWithNew() && typeof returnValue !== 'object') {
returnValue = thisValue;
}
} catch (e) {
push.call(this.returnValues, undefined);
exception = e;
throw e;
} finally {
push.call(this.exceptions, exception);
}
push.call(this.exceptions, exception);
push.call(this.returnValues, returnValue);
createCallProperties.call(this);
if (exception !== undefined) {
throw exception;
}
return returnValue;
},
@ -366,6 +183,17 @@ if (!this.sinon && commonJSModule) {
this.callIds[i]);
},
getCalls: function () {
var calls = [];
var i;
for (i = 0; i < this.callCount; i++) {
calls.push(this.getCall(i));
}
return calls;
},
calledBefore: function calledBefore(spyFn) {
if (!this.called) {
return false;
@ -402,6 +230,7 @@ if (!this.sinon && commonJSModule) {
var original = this;
var fake = this._create();
fake.matchingAguments = args;
fake.parent = this;
push.call(this.fakes, fake);
fake.withArgs = function () {
@ -442,7 +271,7 @@ if (!this.sinon && commonJSModule) {
if (typeof formatter == "function") {
return formatter.call(null, spy, args);
} else if (!isNaN(parseInt(specifyer), 10)) {
} else if (!isNaN(parseInt(specifyer, 10))) {
return sinon.format(args[specifyer - 1]);
}

View File

@ -1,6 +1,7 @@
/**
* @depend ../sinon.js
* @depend spy.js
* @depend behavior.js
*/
/*jslint eqeqeq: false, onevar: false*/
/*global module, require, sinon*/
@ -15,7 +16,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");
@ -38,11 +39,11 @@
wrapper = stub.create();
}
if (!object && !property) {
if (!object && typeof property === "undefined") {
return sinon.stub.create();
}
if (!property && !!object && typeof object == "object") {
if (typeof property === "undefined" && typeof object == "object") {
for (var prop in object) {
if (typeof object[prop] === "function") {
stub(object, prop);
@ -55,128 +56,26 @@
return sinon.wrapMethod(object, property, wrapper);
}
function getChangingValue(stub, property) {
var index = stub.callCount - 1;
var values = stub[property];
var prop = index in values ? values[index] : values[values.length - 1];
stub[property + "Last"] = prop;
return prop;
function getDefaultBehavior(stub) {
return stub.defaultBehavior || getParentBehaviour(stub) || sinon.behavior.create(stub);
}
function getCallback(stub, args) {
var callArgAt = getChangingValue(stub, "callArgAts");
if (callArgAt < 0) {
var callArgProp = getChangingValue(stub, "callArgProps");
for (var i = 0, l = args.length; i < l; ++i) {
if (!callArgProp && typeof args[i] == "function") {
return args[i];
}
if (callArgProp && args[i] &&
typeof args[i][callArgProp] == "function") {
return args[i][callArgProp];
}
}
return null;
}
return args[callArgAt];
function getParentBehaviour(stub) {
return (stub.parent && getCurrentBehavior(stub.parent));
}
var join = Array.prototype.join;
function getCallbackError(stub, func, args) {
if (stub.callArgAtsLast < 0) {
var msg;
if (stub.callArgPropsLast) {
msg = sinon.functionName(stub) +
" expected to yield to '" + stub.callArgPropsLast +
"', but no object with such a property was passed."
} else {
msg = sinon.functionName(stub) +
" expected to yield, but no callback was passed."
}
if (args.length > 0) {
msg += " Received [" + join.call(args, ", ") + "]";
}
return msg;
}
return "argument at index " + stub.callArgAtsLast + " is not a function: " + func;
}
var nextTick = (function () {
if (typeof process === "object" && typeof process.nextTick === "function") {
return process.nextTick;
} else if (typeof setImmediate === "function") {
return setImmediate;
} else {
return function (callback) {
setTimeout(callback, 0);
};
}
})();
function callCallback(stub, args) {
if (stub.callArgAts.length > 0) {
var func = getCallback(stub, args);
if (typeof func != "function") {
throw new TypeError(getCallbackError(stub, func, args));
}
var callbackArguments = getChangingValue(stub, "callbackArguments");
var callbackContext = getChangingValue(stub, "callbackContexts");
if (stub.callbackAsync) {
nextTick(function() {
func.apply(callbackContext, callbackArguments);
});
} else {
func.apply(callbackContext, callbackArguments);
}
}
function getCurrentBehavior(stub) {
var behavior = stub.behaviors[stub.callCount - 1];
return behavior && behavior.isPresent() ? behavior : getDefaultBehavior(stub);
}
var uuid = 0;
sinon.extend(stub, (function () {
var slice = Array.prototype.slice, proto;
function throwsException(error, message) {
if (typeof error == "string") {
this.exception = new Error(message || "");
this.exception.name = error;
} else if (!error) {
this.exception = new Error("Error");
} else {
this.exception = error;
}
return this;
}
proto = {
var proto = {
create: function create() {
var functionStub = function () {
callCallback(functionStub, arguments);
if (functionStub.exception) {
throw functionStub.exception;
} else if (typeof functionStub.returnArgAt == 'number') {
return arguments[functionStub.returnArgAt];
} else if (functionStub.returnThis) {
return this;
}
return functionStub.returnValue;
return getCurrentBehavior(functionStub).invoke(this, arguments);
};
functionStub.id = "stub#" + uuid++;
@ -184,26 +83,22 @@
functionStub = sinon.spy.create(functionStub);
functionStub.func = orig;
functionStub.callArgAts = [];
functionStub.callbackArguments = [];
functionStub.callbackContexts = [];
functionStub.callArgProps = [];
sinon.extend(functionStub, stub);
functionStub._create = sinon.stub.create;
functionStub.displayName = "stub";
functionStub.toString = sinon.functionToString;
functionStub.defaultBehavior = null;
functionStub.behaviors = [];
return functionStub;
},
resetBehavior: function () {
var i;
this.callArgAts = [];
this.callbackArguments = [];
this.callbackContexts = [];
this.callArgProps = [];
this.defaultBehavior = null;
this.behaviors = [];
delete this.returnValue;
delete this.returnArgAt;
@ -216,151 +111,44 @@
}
},
returns: function returns(value) {
this.returnValue = value;
return this;
},
returnsArg: function returnsArg(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
onCall: function(index) {
if (!this.behaviors[index]) {
this.behaviors[index] = sinon.behavior.create(this);
}
this.returnArgAt = pos;
return this;
return this.behaviors[index];
},
returnsThis: function returnsThis() {
this.returnThis = true;
return this;
onFirstCall: function() {
return this.onCall(0);
},
"throws": throwsException,
throwsException: throwsException,
callsArg: function callsArg(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.callArgAts.push(pos);
this.callbackArguments.push([]);
this.callbackContexts.push(undefined);
this.callArgProps.push(undefined);
return this;
onSecondCall: function() {
return this.onCall(1);
},
callsArgOn: function callsArgOn(pos, context) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAts.push(pos);
this.callbackArguments.push([]);
this.callbackContexts.push(context);
this.callArgProps.push(undefined);
return this;
},
callsArgWith: function callsArgWith(pos) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
this.callArgAts.push(pos);
this.callbackArguments.push(slice.call(arguments, 1));
this.callbackContexts.push(undefined);
this.callArgProps.push(undefined);
return this;
},
callsArgOnWith: function callsArgWith(pos, context) {
if (typeof pos != "number") {
throw new TypeError("argument index is not number");
}
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAts.push(pos);
this.callbackArguments.push(slice.call(arguments, 2));
this.callbackContexts.push(context);
this.callArgProps.push(undefined);
return this;
},
yields: function () {
this.callArgAts.push(-1);
this.callbackArguments.push(slice.call(arguments, 0));
this.callbackContexts.push(undefined);
this.callArgProps.push(undefined);
return this;
},
yieldsOn: function (context) {
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAts.push(-1);
this.callbackArguments.push(slice.call(arguments, 1));
this.callbackContexts.push(context);
this.callArgProps.push(undefined);
return this;
},
yieldsTo: function (prop) {
this.callArgAts.push(-1);
this.callbackArguments.push(slice.call(arguments, 1));
this.callbackContexts.push(undefined);
this.callArgProps.push(prop);
return this;
},
yieldsToOn: function (prop, context) {
if (typeof context != "object") {
throw new TypeError("argument context is not an object");
}
this.callArgAts.push(-1);
this.callbackArguments.push(slice.call(arguments, 2));
this.callbackContexts.push(context);
this.callArgProps.push(prop);
return this;
onThirdCall: function() {
return this.onCall(2);
}
};
// create asynchronous versions of callsArg* and yields* methods
for (var method in proto) {
// need to avoid creating anotherasync versions of the newly added async methods
if (proto.hasOwnProperty(method) &&
method.match(/^(callsArg|yields|thenYields$)/) &&
!method.match(/Async/)) {
proto[method + 'Async'] = (function (syncFnName) {
return function () {
this.callbackAsync = true;
return this[syncFnName].apply(this, arguments);
for (var method in sinon.behavior) {
if (sinon.behavior.hasOwnProperty(method) &&
!proto.hasOwnProperty(method) &&
method != 'create' &&
method != 'withArgs' &&
method != 'invoke') {
proto[method] = (function(behaviorMethod) {
return function() {
this.defaultBehavior = this.defaultBehavior || sinon.behavior.create(this);
this.defaultBehavior[behaviorMethod].apply(this.defaultBehavior, arguments);
return this;
};
})(method);
}(method));
}
}
return proto;
}()));
if (commonJSModule) {

View File

@ -17,7 +17,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");

View File

@ -15,7 +15,7 @@
"use strict";
(function (sinon) {
var commonJSModule = typeof module == "object" && typeof require == "function";
var commonJSModule = typeof module !== 'undefined' && module.exports;
if (!sinon && commonJSModule) {
sinon = require("../sinon");

View File

@ -41,13 +41,13 @@ if (typeof sinon == "undefined") {
};
sinon.EventTarget = {
addEventListener: function addEventListener(event, listener, useCapture) {
addEventListener: function addEventListener(event, listener) {
this.eventListeners = this.eventListeners || {};
this.eventListeners[event] = this.eventListeners[event] || [];
push.call(this.eventListeners[event], listener);
},
removeEventListener: function removeEventListener(event, listener, useCapture) {
removeEventListener: function removeEventListener(event, listener) {
var listeners = this.eventListeners && this.eventListeners[event] || [];
for (var i = 0, l = listeners.length; i < l; ++i) {

View File

@ -57,7 +57,6 @@ sinon.fakeServer = (function () {
}
function match(response, request) {
var requestMethod = this.getHTTPMethod(request);
var requestUrl = request.url;
if (!/^https?:\/\//.test(requestUrl) || rCurrLoc.test(requestUrl)) {
@ -67,7 +66,7 @@ sinon.fakeServer = (function () {
if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
if (typeof response.response == "function") {
var ru = response.url;
var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
return response.response.apply(response, args);
}
@ -105,16 +104,16 @@ sinon.fakeServer = (function () {
xhrObj.onSend = function () {
server.handleRequest(this);
if (server.autoRespond && !server.responding) {
setTimeout(function () {
server.responding = false;
server.respond();
}, server.autoRespondAfter || 10);
server.responding = true;
}
};
if (this.autoRespond && !this.responding) {
setTimeout(function () {
server.responding = false;
server.respond();
}, this.autoRespondAfter || 10);
this.responding = true;
}
},
getHTTPMethod: function getHTTPMethod(request) {
@ -167,9 +166,10 @@ sinon.fakeServer = (function () {
respond: function respond() {
if (arguments.length > 0) this.respondWith.apply(this, arguments);
var queue = this.queue || [];
var requests = queue.splice(0);
var request;
while(request = queue.shift()) {
while(request = requests.shift()) {
this.processRequest(request);
}
},
@ -183,7 +183,7 @@ sinon.fakeServer = (function () {
var response = this.response || [404, {}, ""];
if (this.responses) {
for (var i = 0, l = this.responses.length; i < l; i++) {
for (var l = this.responses.length, i = l - 1; i >= 0; i--) {
if (match.call(this, this.responses[i], request)) {
response = this.responses[i].response;
break;
@ -207,6 +207,6 @@ sinon.fakeServer = (function () {
};
}());
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

View File

@ -31,6 +31,10 @@ if (typeof sinon == "undefined") {
throw new Error("Function requires at least 1 parameter");
}
if (typeof args[0] === "undefined") {
throw new Error("Callback must be provided to timer calls");
}
var toId = id++;
var delay = args[1] || 0;
@ -132,6 +136,16 @@ if (typeof sinon == "undefined") {
this.clearTimeout(timerId);
},
setImmediate: function setImmediate(callback) {
var passThruArgs = Array.prototype.slice.call(arguments, 1);
return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
},
clearImmediate: function clearImmediate(timerId) {
this.clearTimeout(timerId);
},
tick: function tick(ms) {
ms = typeof ms == "number" ? ms : parseTime(ms);
var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
@ -162,7 +176,7 @@ if (typeof sinon == "undefined") {
},
firstTimerInRange: function (from, to) {
var timer, smallest, originalTimer;
var timer, smallest = null, originalTimer;
for (var id in this.timeouts) {
if (this.timeouts.hasOwnProperty(id)) {
@ -170,7 +184,7 @@ if (typeof sinon == "undefined") {
continue;
}
if (!smallest || this.timeouts[id].callAt < smallest) {
if (smallest === null || this.timeouts[id].callAt < smallest) {
originalTimer = this.timeouts[id];
smallest = this.timeouts[id].callAt;
@ -276,21 +290,39 @@ if (typeof sinon == "undefined") {
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
return target;
}
var methods = ["Date", "setTimeout", "setInterval",
"clearTimeout", "clearInterval"];
if (typeof global.setImmediate !== "undefined") {
methods.push("setImmediate");
}
if (typeof global.clearImmediate !== "undefined") {
methods.push("clearImmediate");
}
function restore() {
var method;
for (var i = 0, l = this.methods.length; i < l; i++) {
method = this.methods[i];
if (global[method].hadOwnProperty) {
global[method] = this["_" + method];
} else {
delete global[method];
try {
delete global[method];
} catch (e) {}
}
}
@ -341,11 +373,13 @@ if (typeof sinon == "undefined") {
sinon.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

View File

@ -14,13 +14,14 @@
*/
"use strict";
if (typeof sinon == "undefined") {
this.sinon = {};
}
sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
// wrapper for global
(function(global) {
if (typeof sinon === "undefined") {
global.sinon = {};
}
sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
var xhr = sinon.xhr;
xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
xhr.GlobalActiveXObject = global.ActiveXObject;
@ -28,6 +29,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
xhr.supportsXHR = typeof xhr.GlobalXMLHttpRequest != "undefined";
xhr.workingXHR = xhr.supportsXHR ? xhr.GlobalXMLHttpRequest : xhr.supportsActiveX
? function() { return new xhr.GlobalActiveXObject("MSXML2.XMLHTTP.3.0") } : false;
xhr.supportsCORS = 'withCredentials' in (new sinon.xhr.GlobalXMLHttpRequest());
/*jsl:ignore*/
var unsafeHeaders = {
@ -58,6 +60,11 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.requestBody = null;
this.status = 0;
this.statusText = "";
this.upload = new UploadProgress();
if (sinon.xhr.supportsCORS) {
this.withCredentials = false;
}
var xhr = this;
var events = ["loadstart", "load", "abort", "loadend"];
@ -81,6 +88,41 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
}
}
// An upload object is created for each
// FakeXMLHttpRequest and allows upload
// events to be simulated using uploadProgress
// and uploadError.
function UploadProgress() {
this.eventListeners = {
"progress": [],
"load": [],
"abort": [],
"error": []
}
}
UploadProgress.prototype.addEventListener = function(event, listener) {
this.eventListeners[event].push(listener);
};
UploadProgress.prototype.removeEventListener = function(event, listener) {
var listeners = this.eventListeners[event] || [];
for (var i = 0, l = listeners.length; i < l; ++i) {
if (listeners[i] == listener) {
return listeners.splice(i, 1);
}
}
};
UploadProgress.prototype.dispatchEvent = function(event) {
var listeners = this.eventListeners[event.type] || [];
for (var i = 0, listener; (listener = listeners[i]) != null; i++) {
listener(event);
}
};
function verifyState(xhr) {
if (xhr.readyState !== FakeXMLHttpRequest.OPENED) {
throw new Error("INVALID_STATE_ERR");
@ -102,7 +144,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
function some(collection, callback) {
for (var index = 0; index < collection.length; index++) {
if(callback(collection[index]) === true) return true;
};
}
return false;
}
// largest arity in XHR is 5 - XHR#open
@ -114,7 +156,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
case 3: return obj[method](args[0],args[1],args[2]);
case 4: return obj[method](args[0],args[1],args[2],args[3]);
case 5: return obj[method](args[0],args[1],args[2],args[3],args[4]);
};
}
};
FakeXMLHttpRequest.filters = [];
@ -153,7 +195,7 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
if(xhr.readyState === FakeXMLHttpRequest.DONE) {
copyAttrs(["responseXML"]);
}
if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr);
if(fakeXhr.onreadystatechange) fakeXhr.onreadystatechange.call(fakeXhr, { target: fakeXhr });
};
if(xhr.addEventListener) {
for(var event in fakeXhr.eventListeners) {
@ -234,6 +276,8 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
case FakeXMLHttpRequest.DONE:
this.dispatchEvent(new sinon.Event("load", false, false, this));
this.dispatchEvent(new sinon.Event("loadend", false, false, this));
this.upload.dispatchEvent(new sinon.Event("load", false, false, this));
this.upload.dispatchEvent(new ProgressEvent("progress", {loaded: 100, total: 100}));
break;
}
},
@ -309,6 +353,9 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.readyState = sinon.FakeXMLHttpRequest.UNSENT;
this.dispatchEvent(new sinon.Event("abort", false, false, this));
this.upload.dispatchEvent(new sinon.Event("abort", false, false, this));
if (typeof this.onerror === "function") {
this.onerror();
}
@ -392,10 +439,14 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.status = typeof status == "number" ? status : 200;
this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
this.setResponseBody(body || "");
if (typeof this.onload === "function"){
this.onload();
}
},
uploadProgress: function uploadProgress(progressEventRaw) {
this.upload.dispatchEvent(new ProgressEvent("progress", progressEventRaw));
},
uploadError: function uploadError(error) {
this.upload.dispatchEvent(new CustomEvent("error", {"detail": error}));
}
});
@ -502,8 +553,9 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
};
sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
})(this);
if (typeof module == "object" && typeof require == "function") {
})(typeof global === "object" ? global : this);
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

View File

@ -14,6 +14,8 @@
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
@ -22,6 +24,8 @@ function Date() {}
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;

View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- 0.6

View File

@ -0,0 +1,6 @@
Buster.JS Format was written by
Christian Johansen, christian@cjohansen.no
August Lilleaas, august.lilleaas@gmail.com
Dave Geddes, davidcgeddes@gmail.com
Stein Magnus Jodal, stein.magnus@jodal.no
Tek Nynja, github@teknynja.com

View File

@ -0,0 +1,27 @@
(The BSD License)
Copyright (c) 2010-2012, Christian Johansen (christian@cjohansen.no) and
August Lilleaas (august.lilleaas@gmail.com). All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Christian Johansen nor the names of his contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,244 @@
.. default-domain:: js
.. highlight:: javascript
========
formatio
========
The cheesy object formatter
.. raw:: html
<a href="http://travis-ci.org/busterjs/formatio" class="travis">
<img src="https://secure.travis-ci.org/busterjs/formatio.png">
</a>
Pretty formatting of arbitrary JavaScript values. Currently only supports ascii
formatting, suitable for command-line utilities. Like ``JSON.stringify``, it
formats objects recursively, but unlike ``JSON.stringify``, it can handle
regular expressions, functions, circular objects and more.
``formatio`` is a general-purpose library. It works in browsers (including old
and rowdy ones, like IE6) and Node. It will define itself as an AMD module if
you want it to (i.e. if there's a ``define`` function available).
Running tests
=============
::
npm test
Or use Buster.JS manually:
::
node_modules/buster/bin/buster-test --help
``formatio.ascii`` API
======================
``formatio.ascii`` can take any JavaScript object and format it nicely as plain
text. It uses the helper functions described below to format different types of
objects.
``formatio.ascii(object)``
--------------------------
``object`` can be any kind of object, including DOM elements.
**Simple object**
::
var formatio = require("formatio");
var object = { name: "Christian" };
console.log(formatio.ascii(object));
// Outputs:
// { name: "Christian" }
**Complex object**
::
var formatio = require("formatio");
var developer = {
name: "Christian",
interests: ["Programming", "Guitar", "TV"],
location: {
language: "Norway",
city: "Oslo",
getLatLon: function getLatLon(callback) {
// ...
},
distanceTo: function distanceTo(location) {
}
},
speak: function () {
return "Oh hi!";
}
};
console.log(formatio.ascii(developer));
// Outputs:
// {
// interests: ["Programming", "Guitar", "TV"],
// location: {
// city: "Oslo",
// distanceTo: function distanceTo() {},
// getLatLon: function getLatLon() {},
// language: "Norway"
// },
// name: "Christian",
// speak: function () {}
// }
**Custom constructor**
If the object to format is not a generic ``Object`` object, **formatio**
displays the type of object (i.e. name of constructor). Set the
``excludeConstructors`` (see below) property to control what constructors to
include in formatted output.
::
var formatio = require("formatio");
function Person(name) { this.name = name; }
var dude = new Person("Dude");
console.log(format.ascii(dude));
// Outputs:
// [Person] { name: "Dude" }
**DOM elements**
DOM elements are formatted as abbreviated HTML source. 20 characters of
``innerHTML`` is included, and if the content is longer, it is truncated with
``"[...]"``. Future editions will add the possibility to format nested markup
structures.
::
var p = document.createElement("p");
p.id = "sample";
p.className = "notice";
p.setAttribute("data-custom", "42");
p.innerHTML = "Hey there, here's some text for ya there buddy";
console.log(formatio.ascii(p));
// Outputs
// &lt;p id="sample" class="notice" data-custom="42"&gt;Hey there, here's so[...]&lt;/p&gt;</code></pre>
``formatio.ascii.func(func)``
-----------------------------
Formats a function like ``"function [name]() {}"``. The name is retrieved from
``formatio.functionName``.
``formatio.ascii.array(array)``
-------------------------------
Formats an array as ``"[item1, item2, item3]"`` where each item is formatted
with ``formatio.ascii``. Circular references are represented in the resulting
string as ``"[Circular]"``.
``formatio.ascii.object(object)``
Formats all properties of the object with ``formatio.ascii``. If the object can
be fully represented in 80 characters, it's formatted in one line. Otherwise,
it's nicely indented over as many lines as necessary. Circular references are
represented by ``"[Circular]"``.
Objects created with custom constructors will be formatted as
``"[ConstructorName] { ... }"``. Set the ``excludeConstructors`` property to
control what constructors are included in the output like this.
``formatio.ascii.element(element)``
-----------------------------------
Formats a DOM element as HTML source. The tag name is represented in lower-case
and all attributes and their values are included. The element's content is
included, up to 20 characters. If the length exceeds 20 characters, it's
truncated with a ``"[...]"``.
``formatio.functionName(func)``
----------------------
Guesses a function's name. If the function defines the ``displayName`` property
(used by `some debugging tools <http://trac.webkit.org/changeset/42478>`_) it is
preferred. If it is not found, the ``name`` property is tried. If no name can be
found this way, an attempt is made to find the function name by looking at the
function's ``toString()`` representation.
``formatio.constructorName(object)``
------------------------------------
Attempts to guess the name of the constructor that created the object. It does
so by getting the name of ``object.constructor`` using ``functionName``. If a
name is found, ``excludeConstructors`` is consulted. If the constructor name
matches any of these elements, an empty string is returned, otherwise the name
is returned.
``formatio.ascii`` properties
=============================
``quoteStrings`` (``true``)
---------------------------
Whether or not to quote simple strings. When set to ``false``, simple strings
are not quoted. Strings in arrays and objects will still be quoted, but
``ascii("Some string")`` will not gain additional quotes.
``excludeConstructors`` (``["Object", /^.$/]``)
-----------------------------------------------
An array of strings and/or regular expressions naming constructors that should
be stripped from the formatted output. The default value skips objects created
by ``Object`` and constructors that have one character names (which are
typically used in ``Object.create`` shims).
While you can set this property directly on ``formatio.ascii``, it is
recommended to create an instance of ``formatio.ascii`` and override the
property on that object.
**Strings** represent constructor names that should not be represented in the
formatted output. **Regular expressions** are tested against constructor names
when formatting. If the expression is a match, the constructor name is not
included in the formatted output.
::
function Person(name) {
this.name = name;
}
var person = new Person("Chris");
console.log(formatio.ascii(person));
// Outputs
// [Person] { name: "Chris" }
var formatter = Object.create(formatio);
formatter.excludeConstructors = ["Object", /^.$/, "Person"];
console.log(formatter.ascii(person));
// Outputs
// { name: "Chris" }
// Global overwrite, generally not recommended
formatio.excludeConstructors = ["Object", /^.$/, "Person"];
console.log(formatio.ascii(person));
// Outputs
// { name: "Chris" }

View File

@ -0,0 +1,23 @@
module.exports = {
paths: [
"lib/*.js",
"test/*.js"
],
linterOptions: {
node: true,
browser: true,
plusplus: true,
vars: true,
nomen: true,
forin: true,
sloppy: true,
regexp: true,
predef: [
"samsam",
"define",
"assert",
"refute",
"buster"
]
}
};

View File

@ -0,0 +1,14 @@
exports["Browser"] = {
// TODO: Needs fixing
libs: [
"node_modules/samsam/node_modules/lodash/lodash.js",
"node_modules/samsam/lib/samsam.js"
],
sources: ["lib/*.js"],
tests: ["test/*-test.js"]
};
exports["Node"] = {
extends: "Browser",
environment: "node"
};

View File

@ -0,0 +1,199 @@
((typeof define === "function" && define.amd && function (m) {
define("formatio", ["samsam"], m);
}) || (typeof module === "object" && function (m) {
module.exports = m(require("samsam"));
}) || function (m) { this.formatio = m(this.samsam); }
)(function (samsam) {
"use strict";
var formatio = {
excludeConstructors: ["Object", /^.$/],
quoteStrings: true
};
var hasOwn = Object.prototype.hasOwnProperty;
var specialObjects = [];
if (typeof global !== "undefined") {
specialObjects.push({ object: global, value: "[object global]" });
}
if (typeof document !== "undefined") {
specialObjects.push({
object: document,
value: "[object HTMLDocument]"
});
}
if (typeof window !== "undefined") {
specialObjects.push({ object: window, value: "[object Window]" });
}
function functionName(func) {
if (!func) { return ""; }
if (func.displayName) { return func.displayName; }
if (func.name) { return func.name; }
var matches = func.toString().match(/function\s+([^\(]+)/m);
return (matches && matches[1]) || "";
}
function constructorName(f, object) {
var name = functionName(object && object.constructor);
var excludes = f.excludeConstructors ||
formatio.excludeConstructors || [];
var i, l;
for (i = 0, l = excludes.length; i < l; ++i) {
if (typeof excludes[i] === "string" && excludes[i] === name) {
return "";
} else if (excludes[i].test && excludes[i].test(name)) {
return "";
}
}
return name;
}
function isCircular(object, objects) {
if (typeof object !== "object") { return false; }
var i, l;
for (i = 0, l = objects.length; i < l; ++i) {
if (objects[i] === object) { return true; }
}
return false;
}
function ascii(f, object, processed, indent) {
if (typeof object === "string") {
var qs = f.quoteStrings;
var quote = typeof qs !== "boolean" || qs;
return processed || quote ? '"' + object + '"' : object;
}
if (typeof object === "function" && !(object instanceof RegExp)) {
return ascii.func(object);
}
processed = processed || [];
if (isCircular(object, processed)) { return "[Circular]"; }
if (Object.prototype.toString.call(object) === "[object Array]") {
return ascii.array.call(f, object, processed);
}
if (!object) { return String((1/object) === -Infinity ? "-0" : object); }
if (samsam.isElement(object)) { return ascii.element(object); }
if (typeof object.toString === "function" &&
object.toString !== Object.prototype.toString) {
return object.toString();
}
var i, l;
for (i = 0, l = specialObjects.length; i < l; i++) {
if (object === specialObjects[i].object) {
return specialObjects[i].value;
}
}
return ascii.object.call(f, object, processed, indent);
}
ascii.func = function (func) {
return "function " + functionName(func) + "() {}";
};
ascii.array = function (array, processed) {
processed = processed || [];
processed.push(array);
var i, l, pieces = [];
for (i = 0, l = array.length; i < l; ++i) {
pieces.push(ascii(this, array[i], processed));
}
return "[" + pieces.join(", ") + "]";
};
ascii.object = function (object, processed, indent) {
processed = processed || [];
processed.push(object);
indent = indent || 0;
var pieces = [], properties = samsam.keys(object).sort();
var length = 3;
var prop, str, obj, i, l;
for (i = 0, l = properties.length; i < l; ++i) {
prop = properties[i];
obj = object[prop];
if (isCircular(obj, processed)) {
str = "[Circular]";
} else {
str = ascii(this, obj, processed, indent + 2);
}
str = (/\s/.test(prop) ? '"' + prop + '"' : prop) + ": " + str;
length += str.length;
pieces.push(str);
}
var cons = constructorName(this, object);
var prefix = cons ? "[" + cons + "] " : "";
var is = "";
for (i = 0, l = indent; i < l; ++i) { is += " "; }
if (length + indent > 80) {
return prefix + "{\n " + is + pieces.join(",\n " + is) + "\n" +
is + "}";
}
return prefix + "{ " + pieces.join(", ") + " }";
};
ascii.element = function (element) {
var tagName = element.tagName.toLowerCase();
var attrs = element.attributes, attr, pairs = [], attrName, i, l, val;
for (i = 0, l = attrs.length; i < l; ++i) {
attr = attrs.item(i);
attrName = attr.nodeName.toLowerCase().replace("html:", "");
val = attr.nodeValue;
if (attrName !== "contenteditable" || val !== "inherit") {
if (!!val) { pairs.push(attrName + "=\"" + val + "\""); }
}
}
var formatted = "<" + tagName + (pairs.length > 0 ? " " : "");
var content = element.innerHTML;
if (content.length > 20) {
content = content.substr(0, 20) + "[...]";
}
var res = formatted + pairs.join(" ") + ">" + content +
"</" + tagName + ">";
return res.replace(/ contentEditable="inherit"/, "");
};
function Formatio(options) {
for (var opt in options) {
this[opt] = options[opt];
}
}
Formatio.prototype = {
functionName: functionName,
configure: function (options) {
return new Formatio(options);
},
constructorName: function (object) {
return constructorName(this, object);
},
ascii: function (object, processed, indent) {
return ascii(this, object, processed, indent);
}
};
return Formatio.prototype;
});

View File

@ -0,0 +1 @@
/node_modules

View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- 0.6

View File

@ -0,0 +1,2 @@
Christian Johansen (christian@cjohansen.no)
August Lilleaas (august@augustl.com)

View File

@ -0,0 +1,27 @@
(The BSD License)
Copyright (c) 2010-2012, Christian Johansen, christian@cjohansen.no and
August Lilleaas, august.lilleaas@gmail.com. All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Christian Johansen nor the names of his contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -0,0 +1,214 @@
.. default-domain:: js
.. highlight:: javascript
======
samsam
======
Same same, but different
.. raw:: html
<a href="http://travis-ci.org/busterjs/samsam" class="travis">
<img src="https://secure.travis-ci.org/busterjs/samsam.png">
</a>
``samsam`` is a collection of predicate and comparison functions useful for
identifiying the type of values and to compare values with varying degrees of
strictness.
``samsam`` is a general-purpose library with no dependencies. It works in browsers
(including old and rowdy ones, like IE6) and Node. It will define itself as an
AMD module if you want it to (i.e. if there's a ``define`` function available).
``samsam`` was originally extracted from the
`referee <http://github.com/busterjs/referee/>`_ assertion library, which
ships with the Buster.JS testing framework.
Predicate functions
===================
``isArguments(object)``
-----------------------
Returns ``true`` if ``object`` is an ``arguments`` object, ``false`` otherwise.
``isNegZero(value)``
--------------------
Returns ``true`` if ``value`` is ``-0``.
``isElement(object)``
---------------------
Returns ``true`` if ``object`` is a DOM element node. Unlike
Underscore.js/lodash, this function will return ``false`` if ``object`` is an
*element-like* object, i.e. a regular object with a ``nodeType`` property that
holds the value ``1``.
``isDate(object)``
------------------
Returns true if the object is a ``Date``, or *date-like*. Duck typing of date
objects work by checking that the object has a ``getTime`` function whose return
value equals the return value from the object's ``valueOf``.
Comparison functions
====================
``identical(x, y)``
-------------------
Strict equality check according to `EcmaScript Harmony's ``egal``.
**From the Harmony wiki:**
An egal function simply makes available the internal ``SameValue`` function
from section 9.12 of the ES5 spec. If two values are egal, then they are not
observably distinguishable.
``identical`` returns ``true`` when ``===`` is ``true``, except for ``-0`` and
``+0``, where it returns ``false``. Additionally, it returns ``true`` when
``NaN`` is compared to itself.
``deepEqual(obj1, obj2)``
-------------------------
Deep equal comparison. Two values are "deep equal" if:
- They are identical
- They are both date objects representing the same time
- They are both arrays containing elements that are all deepEqual
- They are objects with the same set of properties, and each property
in ``obj1`` is deepEqual to the corresponding property in ``obj2``
``match(object, matcher)``
--------------------------
Partial equality check. Compares ``object`` with matcher according a wide set of
rules:
**String matcher**
In its simplest form, ``match`` performs a case insensitive substring match.
When the matcher is a string, ``object`` is converted to a string, and the
function returns ``true`` if the matcher is a case-insensitive substring of
``object`` as a string.
::
samsam.match("Give me something", "Give"); //true
samsam.match("Give me something", "sumptn"); // false
samsam.match({ toString: function () { return "yeah"; } }, "Yeah!"); // true
The last example is not symmetric. When the matcher is a string, the ``object``
is coerced to a string - in this case using ``toString``. Changing the order of
the arguments would cause the matcher to be an object, in which case different
rules apply (see below).
**Boolean matcher**
Performs a strict (i.e. ``===``) match with the object. So, only ``true``
matches ``true``, and only ``false`` matches ``false``.
**Regular expression matcher**
When the matcher is a regular expression, the function will pass if
``object.test(matcher)`` is ``true``. ``match`` is written in a generic way, so
any object with a ``test`` method will be used as a matcher this way.
::
samsam.match("Give me something", /^[a-z\s]$/i); // true
samsam.match("Give me something", /[0-9]/); // false
samsam.match({ toString: function () { return "yeah!"; } }, /yeah/); // true
samsam.match(234, /[a-z]/); // false
**Number matcher**
When the matcher is a number, the assertion will pass if ``object == matcher``.
::
samsam.match("123", 123); // true
samsam.match("Give me something", 425); // false
samsam.match({ toString: function () { return "42"; } }, 42); // true
samsam.match(234, 1234); // false
**Function matcher**
When the matcher is a function, it is called with ``object`` as its only
argument. ``match`` returns ``true`` if the function returns ``true``. A strict
match is performed against the return value, so a boolean ``true`` is required,
truthy is not enough.
::
// true
samsam.match("123", function (exp) {
return exp == "123";
});
// false
samsam.match("Give me something", function () {
return "ok";
});
// true
samsam.match({
toString: function () {
return "42";
}
}, function () { return true; });
// false
samsam.match(234, function () {});
**Object matcher**
As mentioned above, if an object matcher defines a ``test`` method, ``match``
will return ``true`` if ``matcher.test(object)`` returns truthy.
If the matcher does not have a test method, a recursive match is performed. If
all properties of ``matcher`` matches corresponding properties in ``object``,
``match`` returns ``true``. Note that the object matcher does not care if the
number of properties in the two objects are the same - only if all properties in
the matcher recursively matches ones in ``object``.
::
// true
samsam.match("123", {
test: function (arg) {
return arg == 123;
}
});
// false
samsam.match({}, { prop: 42 });
// true
samsam.match({
name: "Chris",
profession: "Programmer"
}, {
name: "Chris"
});
// false
samsam.match(234, { name: "Chris" });
**DOM elements**
``match`` can be very helpful when comparing DOM elements, because it allows
you to compare several properties with one call:
::
var el = document.getElementById("myEl");
samsam.match(el, {
tagName: "h2",
className: "item",
innerHTML: "Howdy"
});

View File

@ -0,0 +1,23 @@
module.exports = {
paths: [
"lib/*.js",
"test/*.js"
],
linterOptions: {
node: true,
browser: true,
plusplus: true,
vars: true,
nomen: true,
forin: true,
sloppy: true,
eqeq: true,
predef: [
"_",
"define",
"assert",
"refute",
"buster"
]
}
};

View File

@ -0,0 +1,9 @@
server: http://localhost:4224
load:
- node_modules/sinon/lib/sinon.js
- node_modules/sinon/lib/sinon/spy.js
- lib/samsam.js
- node_modules/buster-util/lib/buster-util/test-case.js
- node_modules/buster-util/lib/buster-util/jstestdriver-shim.js
- test/samsam-test.js

View File

@ -0,0 +1,378 @@
((typeof define === "function" && define.amd && function (m) { define("samsam", m); }) ||
(typeof module === "object" &&
function (m) { module.exports = m(); }) || // Node
function (m) { this.samsam = m(); } // Browser globals
)(function () {
var o = Object.prototype;
var div = typeof document !== "undefined" && document.createElement("div");
function isNaN(value) {
// Unlike global isNaN, this avoids type coercion
// typeof check avoids IE host object issues, hat tip to
// lodash
var val = value; // JsLint thinks value !== value is "weird"
return typeof value === "number" && value !== val;
}
function getClass(value) {
// Returns the internal [[Class]] by calling Object.prototype.toString
// with the provided value as this. Return value is a string, naming the
// internal class, e.g. "Array"
return o.toString.call(value).split(/[ \]]/)[1];
}
/**
* @name samsam.isArguments
* @param Object object
*
* Returns ``true`` if ``object`` is an ``arguments`` object,
* ``false`` otherwise.
*/
function isArguments(object) {
if (typeof object !== "object" || typeof object.length !== "number" ||
getClass(object) === "Array") {
return false;
}
if (typeof object.callee == "function") { return true; }
try {
object[object.length] = 6;
delete object[object.length];
} catch (e) {
return true;
}
return false;
}
/**
* @name samsam.isElement
* @param Object object
*
* Returns ``true`` if ``object`` is a DOM element node. Unlike
* Underscore.js/lodash, this function will return ``false`` if ``object``
* is an *element-like* object, i.e. a regular object with a ``nodeType``
* property that holds the value ``1``.
*/
function isElement(object) {
if (!object || object.nodeType !== 1 || !div) { return false; }
try {
object.appendChild(div);
object.removeChild(div);
} catch (e) {
return false;
}
return true;
}
/**
* @name samsam.keys
* @param Object object
*
* Return an array of own property names.
*/
function keys(object) {
var ks = [], prop;
for (prop in object) {
if (o.hasOwnProperty.call(object, prop)) { ks.push(prop); }
}
return ks;
}
/**
* @name samsam.isDate
* @param Object value
*
* Returns true if the object is a ``Date``, or *date-like*. Duck typing
* of date objects work by checking that the object has a ``getTime``
* function whose return value equals the return value from the object's
* ``valueOf``.
*/
function isDate(value) {
return typeof value.getTime == "function" &&
value.getTime() == value.valueOf();
}
/**
* @name samsam.isNegZero
* @param Object value
*
* Returns ``true`` if ``value`` is ``-0``.
*/
function isNegZero(value) {
return value === 0 && 1 / value === -Infinity;
}
/**
* @name samsam.equal
* @param Object obj1
* @param Object obj2
*
* Returns ``true`` if two objects are strictly equal. Compared to
* ``===`` there are two exceptions:
*
* - NaN is considered equal to NaN
* - -0 and +0 are not considered equal
*/
function identical(obj1, obj2) {
if (obj1 === obj2 || (isNaN(obj1) && isNaN(obj2))) {
return obj1 !== 0 || isNegZero(obj1) === isNegZero(obj2);
}
}
/**
* @name samsam.deepEqual
* @param Object obj1
* @param Object obj2
*
* Deep equal comparison. Two values are "deep equal" if:
*
* - They are equal, according to samsam.identical
* - They are both date objects representing the same time
* - They are both arrays containing elements that are all deepEqual
* - They are objects with the same set of properties, and each property
* in ``obj1`` is deepEqual to the corresponding property in ``obj2``
*
* Supports cyclic objects.
*/
function deepEqualCyclic(obj1, obj2) {
// used for cyclic comparison
// contain already visited objects
var objects1 = [],
objects2 = [],
// contain pathes (position in the object structure)
// of the already visited objects
// indexes same as in objects arrays
paths1 = [],
paths2 = [],
// contains combinations of already compared objects
// in the manner: { "$1['ref']$2['ref']": true }
compared = {};
/**
* used to check, if the value of a property is an object
* (cyclic logic is only needed for objects)
* only needed for cyclic logic
*/
function isObject(value) {
if (typeof value === 'object' && value !== null &&
!(value instanceof Boolean) &&
!(value instanceof Date) &&
!(value instanceof Number) &&
!(value instanceof RegExp) &&
!(value instanceof String)) {
return true;
}
return false;
}
/**
* returns the index of the given object in the
* given objects array, -1 if not contained
* only needed for cyclic logic
*/
function getIndex(objects, obj) {
var i;
for (i = 0; i < objects.length; i++) {
if (objects[i] === obj) {
return i;
}
}
return -1;
}
// does the recursion for the deep equal check
return (function deepEqual(obj1, obj2, path1, path2) {
var type1 = typeof obj1;
var type2 = typeof obj2;
// == null also matches undefined
if (obj1 === obj2 ||
isNaN(obj1) || isNaN(obj2) ||
obj1 == null || obj2 == null ||
type1 !== "object" || type2 !== "object") {
return identical(obj1, obj2);
}
// Elements are only equal if identical(expected, actual)
if (isElement(obj1) || isElement(obj2)) { return false; }
var isDate1 = isDate(obj1), isDate2 = isDate(obj2);
if (isDate1 || isDate2) {
if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
return false;
}
}
if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
if (obj1.toString() !== obj2.toString()) { return false; }
}
var class1 = getClass(obj1);
var class2 = getClass(obj2);
var keys1 = keys(obj1);
var keys2 = keys(obj2);
if (isArguments(obj1) || isArguments(obj2)) {
if (obj1.length !== obj2.length) { return false; }
} else {
if (type1 !== type2 || class1 !== class2 ||
keys1.length !== keys2.length) {
return false;
}
}
var key, i, l,
// following vars are used for the cyclic logic
value1, value2,
isObject1, isObject2,
index1, index2,
newPath1, newPath2;
for (i = 0, l = keys1.length; i < l; i++) {
key = keys1[i];
if (!o.hasOwnProperty.call(obj2, key)) {
return false;
}
// Start of the cyclic logic
value1 = obj1[key];
value2 = obj2[key];
isObject1 = isObject(value1);
isObject2 = isObject(value2);
// determine, if the objects were already visited
// (it's faster to check for isObject first, than to
// get -1 from getIndex for non objects)
index1 = isObject1 ? getIndex(objects1, value1) : -1;
index2 = isObject2 ? getIndex(objects2, value2) : -1;
// determine the new pathes of the objects
// - for non cyclic objects the current path will be extended
// by current property name
// - for cyclic objects the stored path is taken
newPath1 = index1 !== -1
? paths1[index1]
: path1 + '[' + JSON.stringify(key) + ']';
newPath2 = index2 !== -1
? paths2[index2]
: path2 + '[' + JSON.stringify(key) + ']';
// stop recursion if current objects are already compared
if (compared[newPath1 + newPath2]) {
return true;
}
// remember the current objects and their pathes
if (index1 === -1 && isObject1) {
objects1.push(value1);
paths1.push(newPath1);
}
if (index2 === -1 && isObject2) {
objects2.push(value2);
paths2.push(newPath2);
}
// remember that the current objects are already compared
if (isObject1 && isObject2) {
compared[newPath1 + newPath2] = true;
}
// End of cyclic logic
// neither value1 nor value2 is a cycle
// continue with next level
if (!deepEqual(value1, value2, newPath1, newPath2)) {
return false;
}
}
return true;
}(obj1, obj2, '$1', '$2'));
}
var match;
function arrayContains(array, subset) {
if (subset.length === 0) { return true; }
var i, l, j, k;
for (i = 0, l = array.length; i < l; ++i) {
if (match(array[i], subset[0])) {
for (j = 0, k = subset.length; j < k; ++j) {
if (!match(array[i + j], subset[j])) { return false; }
}
return true;
}
}
return false;
}
/**
* @name samsam.match
* @param Object object
* @param Object matcher
*
* Compare arbitrary value ``object`` with matcher.
*/
match = function match(object, matcher) {
if (matcher && typeof matcher.test === "function") {
return matcher.test(object);
}
if (typeof matcher === "function") {
return matcher(object) === true;
}
if (typeof matcher === "string") {
matcher = matcher.toLowerCase();
var notNull = typeof object === "string" || !!object;
return notNull &&
(String(object)).toLowerCase().indexOf(matcher) >= 0;
}
if (typeof matcher === "number") {
return matcher === object;
}
if (typeof matcher === "boolean") {
return matcher === object;
}
if (getClass(object) === "Array" && getClass(matcher) === "Array") {
return arrayContains(object, matcher);
}
if (matcher && typeof matcher === "object") {
var prop;
for (prop in matcher) {
if (!match(object[prop], matcher[prop])) {
return false;
}
}
return true;
}
throw new Error("Matcher was not a string, a number, a " +
"function, a boolean or an object");
};
return {
isArguments: isArguments,
isElement: isElement,
isDate: isDate,
isNegZero: isNegZero,
identical: identical,
deepEqual: deepEqualCyclic,
match: match,
keys: keys
};
});

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,344 @@
if (typeof module === "object" && typeof require === "function") {
var buster = require("buster");
var samsam = require("../lib/samsam");
}
(function () {
function tests(method, body) {
var tc = {};
function pass(name) {
var args = Array.prototype.slice.call(arguments, 1);
tc["should return true for " + name] = function () {
assert(samsam[method].apply(samsam, args));
};
}
function fail(name) {
var args = Array.prototype.slice.call(arguments, 1);
tc["should return false for " + name] = function () {
assert(!samsam[method].apply(samsam, args));
};
}
function shouldThrow(name) {
var args = Array.prototype.slice.call(arguments, 1);
try {
samsam[method].apply(samsam, args);
buster.assertion.fail("Expected to throw");
} catch (e) {
assert(true);
}
}
function add(name, func) {
tc[name] = func;
}
body(pass, fail, shouldThrow, add);
buster.testCase(method, tc);
}
tests("isElement", function (pass, fail) {
if (typeof document !== "undefined") {
pass("DOM element node", document.createElement("div"));
fail("DOM text node", document.createTextNode("Hello"));
}
fail("primitive", 42);
fail("object", {});
fail("node-like object", { nodeType: 1 });
});
tests("isNegZero", function (pass, fail) {
pass("-0", -0);
fail("0", 0);
fail("object", {});
});
tests("identical", function (pass, fail) {
var object = { id: 42 };
pass("same object", object, object);
pass("same primitive", 42, 42);
fail("-0 and 0", -0, 0);
pass("NaN and NaN", NaN, NaN);
});
tests("deepEqual", function (pass, fail) {
var func = function () {};
var obj = {};
var arr = [];
var date = new Date();
var sameDate = new Date(date.getTime());
var anotherDate = new Date(date.getTime() - 10);
var sameDateWithProp = new Date(date.getTime());
sameDateWithProp.prop = 42;
pass("object to itself", obj, obj);
pass("strings", "Hey", "Hey");
pass("numbers", 32, 32);
pass("booleans", false, false);
pass("null", null, null);
pass("undefined", undefined, undefined);
pass("function to itself", func, func);
fail("functions", function () {}, function () {});
pass("array to itself", arr, arr);
pass("date objects with same date", date, sameDate);
fail("date objects with different dates", date, anotherDate);
fail("date objects to null", date, null);
fail("date with different custom properties", date, sameDateWithProp);
fail("strings and numbers with coercion", "4", 4);
fail("numbers and strings with coercion", 4, "4");
fail("number object with coercion", 32, new Number(32));
fail("number object reverse with coercion", new Number(32), 32);
fail("falsy values with coercion", 0, "");
fail("falsy values reverse with coercion", "", 0);
fail("string boxing with coercion", "4", new String("4"));
fail("string boxing reverse with coercion", new String("4"), "4");
pass("NaN to NaN", NaN, NaN);
fail("-0 to +0", -0, +0);
fail("-0 to 0", -0, 0);
fail("objects with different own properties",
{ id: 42 }, { id: 42, di: 24 });
fail("objects with different own properties #2",
{ id: undefined }, { di: 24 });
fail("objects with different own properties #3",
{ id: 24 }, { di: undefined });
pass("objects with one property", { id: 42 }, { id: 42 });
pass("objects with one object property",
{ obj: { id: 42 } }, { obj: { id: 42 } });
fail("objects with one property with different values",
{ id: 42 }, { id: 24 });
var deepObject = {
id: 42,
name: "Hey",
sayIt: function () {
return this.name;
},
child: {
speaking: function () {}
}
};
pass("complex objects", deepObject, {
sayIt: deepObject.sayIt,
child: { speaking: deepObject.child.speaking },
id: 42,
name: "Hey"
});
pass("arrays",
[1, 2, "Hey there", func, { id: 42, prop: [2, 3] }],
[1, 2, "Hey there", func, { id: 42, prop: [2, 3] }]);
fail("nested array with shallow array", [["hey"]], ["hey"]);
var arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];
arr1.prop = 42;
fail("arrays with different custom properties", arr1, arr2);
pass("regexp literals", /a/, /a/);
pass("regexp objects", new RegExp("[a-z]+"), new RegExp("[a-z]+"));
var re1 = new RegExp("[a-z]+");
var re2 = new RegExp("[a-z]+");
re2.id = 42;
fail("regexp objects with custom properties", re1, re2);
fail("different objects", { id: 42 }, {});
fail("object to null", {}, null);
fail("object to undefined", {}, undefined);
fail("object to false", {}, false);
fail("false to object", false, {});
fail("object to true", {}, true);
fail("true to object", true, {});
fail("'empty' object to date", {}, new Date());
fail("'empty' object to string object", {}, String());
fail("'empty' object to number object", {}, Number());
fail("'empty' object to empty array", {}, []);
function gather() { return arguments; }
var arrayLike = { length: 4, "0": 1, "1": 2, "2": {}, "3": [] };
pass("arguments to array", [1, 2, {}, []], gather(1, 2, {}, []));
pass("array to arguments", gather(), []);
pass("arguments to array like object",
arrayLike, gather(1, 2, {}, []));
});
/**
* Tests for cyclic objects.
*/
tests("deepEqual", function (pass, fail) {
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = cyclic1;
cyclic2.ref = cyclic2;
pass("equal cyclic objects (cycle on 2nd level)", cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = cyclic1;
cyclic2.ref = cyclic2;
cyclic2.ref2 = cyclic2;
fail("different cyclic objects (cycle on 2nd level)",
cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = {};
cyclic1.ref.ref = cyclic1;
cyclic2.ref = {};
cyclic2.ref.ref = cyclic2;
pass("equal cyclic objects (cycle on 3rd level)", cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = {};
cyclic1.ref.ref = cyclic1;
cyclic2.ref = {};
cyclic2.ref.ref = cyclic2;
cyclic2.ref.ref2 = cyclic2;
fail("different cyclic objects (cycle on 3rd level)",
cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = cyclic1;
cyclic2.ref = cyclic1;
pass("equal objects even though only one object is cyclic",
cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {}, cyclic2 = {};
cyclic1.ref = {
ref: cyclic1
};
cyclic2.ref = {};
cyclic2.ref.ref = cyclic2.ref;
pass("referencing different but equal cyclic objects",
cyclic1, cyclic2);
}());
(function () {
var cyclic1 = {a: "a"}, cyclic2 = {a: "a"};
cyclic1.ref = {
b: "b",
ref: cyclic1
};
cyclic2.ref = {
b: "b"
};
cyclic2.ref.ref = cyclic2.ref;
fail("referencing different and unequal cyclic objects",
cyclic1, cyclic2);
}());
});
tests("match", function (pass, fail, shouldThrow, add) {
pass("matching regexp", "Assertions", /[a-z]/);
pass("generic object and test method returning true", "Assertions", {
test: function () { return true; }
});
fail("non-matching regexp", "Assertions 123", /^[a-z]$/);
pass("matching boolean", true, true);
fail("mismatching boolean", true, false);
fail("generic object with test method returning false", "Assertions", {
test: function () { return false; }
});
shouldThrow("match object === null", "Assertions 123", null);
fail("match object === false", "Assertions 123", false);
fail("matching number against string", "Assertions 123", 23);
fail("matching number against similar string", "23", 23);
pass("matching number against itself", 23, 23);
pass("matcher function returns true",
"Assertions 123", function (obj) { return true; });
fail("matcher function returns false",
"Assertions 123", function (obj) { return false; });
fail("matcher function returns falsy",
"Assertions 123", function () {});
fail("matcher does not return explicit true",
"Assertions 123", function () { return "Hey"; });
add("should call matcher with object", function () {
var spy = this.spy();
samsam.match("Assertions 123", spy);
assert.calledWith(spy, "Assertions 123");
});
pass("matcher is substring of matchee", "Diskord", "or");
pass("matcher is string equal to matchee", "Diskord", "Diskord");
pass("strings ignoring case", "Look ma, case-insensitive",
"LoOk Ma, CaSe-InSenSiTiVe");
fail("match string is not substring of matchee", "Vim", "Emacs");
fail("match string is not substring of object", {}, "Emacs");
fail("matcher is not substring of object.toString", {
toString: function () { return "Vim"; }
}, "Emacs");
fail("null and empty string", null, "");
fail("undefined and empty string", undefined, "");
fail("false and empty string", false, "");
fail("0 and empty string", 0, "");
fail("NaN and empty string", NaN, "");
var object = {
id: 42,
name: "Christian",
doIt: "yes",
speak: function () {
return this.name;
}
};
pass("object containing all properties in matcher", object, {
id: 42,
doIt: "yes"
});
var object2 = {
id: 42,
name: "Christian",
doIt: "yes",
owner: {
someDude: "Yes",
hello: "ok"
},
speak: function () {
return this.name;
}
};
pass("nested matcher", object2, {
owner: {
someDude: "Yes",
hello: function (value) {
return value == "ok";
}
}
});
pass("empty strings", "", "");
pass("empty strings as object properties", { foo: "" }, { foo: "" });
pass("similar arrays", [1, 2, 3], [1, 2, 3]);
pass("array subset", [1, 2, 3], [2, 3]);
pass("single-element array subset", [1, 2, 3], [1]);
pass("matching array subset", [1, 2, 3, { id: 42 }], [{ id: 42 }]);
fail("mis-matching array 'subset'", [1, 2, 3], [2, 3, 4]);
fail("mis-ordered array 'subset'", [1, 2, 3], [1, 3]);
pass("empty arrays", [], []);
pass("objects with empty arrays", { xs: [] }, { xs: [] });
});
}());

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,374 @@
/*global formatio*/
((typeof module === "object" && typeof require === "function" && function (t) {
t(require("buster"), require("../lib/formatio"));
}) || function (t) {
t(buster, formatio);
})(function (buster, formatio) {
buster.testCase("formatio.ascii", {
"formats strings with quotes": function () {
assert.equals(formatio.ascii("A string"), '"A string"');
},
"formats booleans without quotes": function () {
assert.equals(formatio.ascii(true), "true");
assert.equals(formatio.ascii(false), "false");
},
"formats null and undefined without quotes": function () {
assert.equals(formatio.ascii(null), "null");
assert.equals(formatio.ascii(undefined), "undefined");
},
"formats numbers without quotes": function () {
assert.equals(formatio.ascii(3), "3");
assert.equals(formatio.ascii(3987.56), "3987.56");
assert.equals(formatio.ascii(-980.0), "-980");
assert.equals(formatio.ascii(NaN), "NaN");
assert.equals(formatio.ascii(Infinity), "Infinity");
assert.equals(formatio.ascii(-Infinity), "-Infinity");
assert.equals(formatio.ascii(-0), "-0");
},
"formats regexp using toString": function () {
assert.equals(formatio.ascii(/[a-zA-Z0-9]+\.?/),
"/[a-zA-Z0-9]+\\.?/");
},
"formats functions with name": function () {
var fn = function doIt() {};
assert.equals(formatio.ascii(fn), "function doIt() {}");
},
"formats functions without name": function () {
assert.equals(formatio.ascii(function () {}), "function () {}");
},
"formats functions with display name": function () {
function doIt() {}
doIt.displayName = "ohHai";
assert.equals(formatio.ascii(doIt), "function ohHai() {}");
},
"shortens functions with long bodies": function () {
function doIt() {
var i;
function hey() {}
for (i = 0; i < 10; i++) { console.log(i); }
}
assert.equals(formatio.ascii(doIt), "function doIt() {}");
},
"formats functions with no name or display name": function () {
function doIt() {}
doIt.name = "";
assert.equals(formatio.ascii(doIt), "function doIt() {}");
},
"formats arrays": function () {
function ohNo() { return "Oh yes!"; }
var array = ["String", 123, /a-z/, null];
var str = formatio.ascii(array);
assert.equals(str, '["String", 123, /a-z/, null]');
str = formatio.ascii([ohNo, array]);
assert.equals(str,
'[function ohNo() {}, ["String", 123, /a-z/, null]]');
},
"does not trip on circular arrays": function () {
var array = ["String", 123, /a-z/];
array.push(array);
var str = formatio.ascii(array);
assert.equals(str, '["String", 123, /a-z/, [Circular]]');
},
"formats object": function () {
var object = {
id: 42,
hello: function () {},
prop: "Some",
more: "properties",
please: "Gimme some more",
"oh hi": 42,
seriously: "many properties"
};
var expected = "{\n hello: function () {},\n id: 42,\n " +
"more: \"properties\",\n \"oh hi\": 42,\n please: " +
"\"Gimme some more\",\n prop: \"Some\"," +
"\n seriously: \"many properties\"\n}";
assert.equals(formatio.ascii(object), expected);
},
"formats short object on one line": function () {
var object = {
id: 42,
hello: function () {},
prop: "Some"
};
var expected = "{ hello: function () {}, id: 42, prop: \"Some\" }";
assert.equals(formatio.ascii(object), expected);
},
"formats object with a non-function toString": function () {
var object = { toString: 42 };
assert.equals(formatio.ascii(object), "{ toString: 42 }");
},
"formats nested object": function () {
var object = {
id: 42,
hello: function () {},
prop: "Some",
obj: {
num: 23,
string: "Here you go you little mister"
}
};
var expected = "{\n hello: function () {},\n id: 42,\n obj" +
": { num: 23, string: \"Here you go you little mister\"" +
" },\n prop: \"Some\"\n}";
assert.equals(formatio.ascii(object), expected);
},
"includes constructor if known and not Object": function () {
function Person(name) {
this.name = name;
}
var person = new Person("Christian");
assert.equals(formatio.ascii(person),
"[Person] { name: \"Christian\" }");
},
"does not include one letter constructors": function () {
function F(name) {
this.name = name;
}
var person = new F("Christian");
assert.equals(formatio.ascii(person), "{ name: \"Christian\" }");
},
"includes one letter constructors when configured so": function () {
function C(name) {
this.name = name;
}
var person = new C("Christian");
var formatter = formatio.configure({ excludeConstructors: [] });
assert.equals(formatter.ascii(person),
"[C] { name: \"Christian\" }");
},
"excludes constructors when configured to do so": function () {
function Person(name) {
this.name = name;
}
var person = new Person("Christian");
var formatter = formatio.configure({ excludeConstructors: ["Person"] });
assert.equals(formatter.ascii(person), "{ name: \"Christian\" }");
},
"excludes constructors by pattern when configured so": function () {
function Person(name) { this.name = name; }
function Ninja(name) { this.name = name; }
function Pervert(name) { this.name = name; }
var person = new Person("Christian");
var ninja = new Ninja("Haruhachi");
var pervert = new Pervert("Mr. Garrison");
var formatter = formatio.configure({ excludeConstructors: [/^Per/] });
assert.equals(formatter.ascii(person), "{ name: \"Christian\" }");
assert.equals(formatter.ascii(ninja),
"[Ninja] { name: \"Haruhachi\" }");
assert.equals(formatter.ascii(pervert),
"{ name: \"Mr. Garrison\" }");
},
"excludes constructors when run on other objects": function () {
function Person(name) { this.name = name; }
var person = new Person("Christian");
var formatter = { ascii: formatio.ascii };
formatter.excludeConstructors = ["Person"];
assert.equals(formatter.ascii(person), "{ name: \"Christian\" }");
},
"excludes default constructors when run on other objects": function () {
var person = { name: "Christian" };
var formatter = { ascii: formatio.ascii };
assert.equals(formatter.ascii(person), "{ name: \"Christian\" }");
},
"does not trip on circular formatting": function () {
var object = {};
object.foo = object;
assert.equals(formatio.ascii(object), "{ foo: [Circular] }");
},
"does not trip on indirect circular formatting": function () {
var object = { someProp: {} };
object.someProp.foo = object;
assert.equals(formatio.ascii(object),
"{ someProp: { foo: [Circular] } }");
},
"formats nested array nicely": function () {
var object = { people: ["Chris", "August"] };
assert.equals(formatio.ascii(object),
"{ people: [\"Chris\", \"August\"] }");
},
"does not rely on object's hasOwnProperty": function () {
// Create object with no "own" properties to get past
// Object.keys test and no .hasOwnProperty() function
var Obj = function () {};
Obj.prototype = { hasOwnProperty: undefined };
var object = new Obj();
assert.equals(formatio.ascii(object), "{ }");
},
"handles cyclic structures": function () {
var obj = {};
obj.list1 = [obj];
obj.list2 = [obj];
obj.list3 = [{ prop: obj }];
refute.exception(function () {
formatio.ascii(obj);
});
},
"unquoted strings": {
setUp: function () {
this.formatter = formatio.configure({ quoteStrings: false });
},
"does not quote strings": function () {
assert.equals(this.formatter.ascii("Hey there"), "Hey there");
},
"quotes string properties": function () {
var obj = { hey: "Mister" };
assert.equals(this.formatter.ascii(obj), "{ hey: \"Mister\" }");
}
},
"numbers": {
"formats object with 0": function () {
var str = formatio.ascii({ me: 0 });
refute.match(str, "-0");
},
"formats object with -0": function () {
var str = formatio.ascii({ me: -0 });
assert.match(str, "-0");
}
},
"DOM elements": {
requiresSupportFor: { "DOM": typeof document !== "undefined" },
"formats dom element": function () {
var element = document.createElement("div");
assert.equals(formatio.ascii(element), "<div></div>");
},
"formats dom element with attributes": function () {
var element = document.createElement("div");
element.className = "hey there";
element.id = "ohyeah";
var str = formatio.ascii(element);
assert.match(str, /<div (.*)><\/div>/);
assert.match(str, /class="hey there"/);
assert.match(str, /id="ohyeah"/);
},
"formats dom element with content": function () {
var element = document.createElement("div");
element.innerHTML = "Oh hi!";
assert.equals(formatio.ascii(element), "<div>Oh hi!</div>");
},
"truncates dom element content": function () {
var element = document.createElement("div");
element.innerHTML = "Oh hi! I'm Christian, and this " +
"is a lot of content";
assert.equals(formatio.ascii(element),
"<div>Oh hi! I'm Christian[...]</div>");
},
"includes attributes and truncated content": function () {
var element = document.createElement("div");
element.id = "anid";
element.lang = "en";
element.innerHTML = "Oh hi! I'm Christian, and this " +
"is a lot of content";
var str = formatio.ascii(element);
assert.match(str,
/<div (.*)>Oh hi! I'm Christian\[\.\.\.\]<\/div>/);
assert.match(str, /lang="en"/);
assert.match(str, /id="anid"/);
},
"formats document object as toString": function () {
var str;
buster.assertions.refute.exception(function () {
str = formatio.ascii(document);
});
assert.equals(str, "[object HTMLDocument]");
},
"formats window object as toString": function () {
var str;
buster.assertions.refute.exception(function () {
str = formatio.ascii(window);
});
assert.equals(str, "[object Window]");
}
},
"global object": {
requiresSupportFor: { "global": typeof global !== "undefined" },
"formats global object as toString": function () {
var str;
buster.assertions.refute.exception(function () {
str = formatio.ascii(global);
});
assert.equals(str, "[object global]");
}
}
});
});

View File

@ -1,7 +1,7 @@
{
"name": "sinon",
"description": "JavaScript test spies, stubs and mocks.",
"version": "1.7.3",
"version": "1.8.1",
"homepage": "http://cjohansen.no/sinon/",
"author": {
"name": "Christian Johansen"
@ -24,7 +24,7 @@
"prepublish": "./build"
},
"dependencies": {
"buster-format": "~0.5"
"formatio": "~1.0"
},
"devDependencies": {
"buster-core": ">=0.6.4",
@ -37,12 +37,12 @@
"engines": {
"node": ">=0.1.103"
},
"readme": "# Sinon.JS\n\n[![Build status](https://secure.travis-ci.org/cjohansen/Sinon.JS.png?branch=master)](http://travis-ci.org/cjohansen/Sinon.JS)\n\nStandalone and test framework agnostic JavaScript test spies, stubs and mocks.\n\n## Installation\n\nvia [npm (node package manager)](http://github.com/isaacs/npm)\n\n $ npm install sinon\n\nor install via git by cloning the repository and including sinon.js\nin your project, as you would any other third party library.\n\nDon't forget to include the parts of Sinon.JS that you want to use as well\n(i.e. spy.js).\n\n## Usage\n\nSee the [sinon project homepage](http://sinonjs.org/)\n\n## Goals\n\n* No global pollution\n* Easy to use\n* Require minimal “integration”\n* Easy to embed seamlessly with any testing framework\n* Easily fake any interface\n* Ship with ready-to-use fakes for XMLHttpRequest, timers and more\n\n## Contribute?\n\nPick [an issue](http://github.com/cjohansen/Sinon.JS/issues) to fix, or pitch\nnew features. To avoid wasting your time, please ask for feedback on feature\nsuggestions either with [an issue](http://github.com/cjohansen/Sinon.JS/issues/new)\nor on [the mailing list](http://groups.google.com/group/sinonjs).\n\n## Run the tests\n\nThe Sinon.JS developer environment requires Node/NPM. Please make sure you have\nNode installed, and install Sinon's dependencies:\n\n $ npm install\n\n### On Node\n\n $ npm test\n\n### In the browser\n\nOpen `test/sinon.html` in a browser. To test against a built distribution, first\nmake sure you have a build (requires Ruby and Juicer):\n\n $ ./build\n\nThen open `test/sinon-dist.html` in a browser.\n\nIf the build script is unable to find Juicer, try\n\n $ ruby -rubygems build\n\nSome tests needs working XHR to pass. To run the tests over an HTTP server, run\n\n $ node_modules/http-server/bin/http-server\n\nThen open [localhost:8080/test/sinon.html](http://localhost:8080/test/sinon.html)\nin a browser.\n\n### On Rhino\n\nThe Rhino tests are currently out of commission (pending update after switch to\nBuster.JS for tests).\n",
"readme": "# Sinon.JS\n\n[![Build status](https://secure.travis-ci.org/cjohansen/Sinon.JS.png?branch=master)](http://travis-ci.org/cjohansen/Sinon.JS)\n\nStandalone and test framework agnostic JavaScript test spies, stubs and mocks.\n\n## Installation\n\nvia [npm (node package manager)](http://github.com/isaacs/npm)\n\n $ npm install sinon\n\nvia [NuGet (package manager for Microsoft development platform)](https://www.nuget.org/packages/SinonJS)\n\n Install-Package SinonJS\n\nor install via git by cloning the repository and including sinon.js\nin your project, as you would any other third party library.\n\nDon't forget to include the parts of Sinon.JS that you want to use as well\n(i.e. spy.js).\n\n## Usage\n\nSee the [sinon project homepage](http://sinonjs.org/)\n\n## Goals\n\n* No global pollution\n* Easy to use\n* Require minimal “integration”\n* Easy to embed seamlessly with any testing framework\n* Easily fake any interface\n* Ship with ready-to-use fakes for XMLHttpRequest, timers and more\n\n## Contribute?\n\nPick [an issue](http://github.com/cjohansen/Sinon.JS/issues) to fix, or pitch\nnew features. To avoid wasting your time, please ask for feedback on feature\nsuggestions either with [an issue](http://github.com/cjohansen/Sinon.JS/issues/new)\nor on [the mailing list](http://groups.google.com/group/sinonjs).\n\n## Run the tests\n\nThe Sinon.JS developer environment requires Node/NPM. Please make sure you have\nNode installed, and install Sinon's dependencies:\n\n $ npm install\n\n### On Node\n\n $ npm test\n\n### In the browser\n\nOpen `test/sinon.html` in a browser. To test against a built distribution, first\nmake sure you have a build (requires [Ruby][ruby] and [Juicer][juicer]):\n\n $ ./build\n\n[ruby]: https://www.ruby-lang.org/en/\n[juicer]: http://rubygems.org/gems/juicer\n\nThen open `test/sinon-dist.html` in a browser.\n\nIf the build script is unable to find Juicer, try\n\n $ ruby -rubygems build\n\nSome tests needs working XHR to pass. To run the tests over an HTTP server, run\n\n $ node_modules/http-server/bin/http-server\n\nThen open [localhost:8080/test/sinon.html](http://localhost:8080/test/sinon.html)\nin a browser.\n\n### On Rhino\n\nThe Rhino tests are currently out of commission (pending update after switch to\nBuster.JS for tests).\n",
"readmeFilename": "README.md",
"_id": "sinon@1.7.3",
"_id": "sinon@1.8.1",
"dist": {
"shasum": "01a0bdd0516a5d97c1ba5ed3de7cb2a2e10b8f9d"
"shasum": "5f391aef60260ca5ac8fb120f1a8e878b8f595a9"
},
"_from": "sinon@",
"_resolved": "https://registry.npmjs.org/sinon/-/sinon-1.7.3.tgz"
"_from": "sinon@1.8.1",
"_resolved": "https://registry.npmjs.org/sinon/-/sinon-1.8.1.tgz"
}

File diff suppressed because it is too large Load Diff

4721
js/npm/node_modules/sinon/pkg/sinon-1.8.0.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

4721
js/npm/node_modules/sinon/pkg/sinon-1.8.1.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/**
* Sinon.JS 1.7.3, 2013/06/20
* Sinon.JS 1.7.3, 2013/10/18
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS

86
js/npm/node_modules/sinon/pkg/sinon-ie-1.8.0.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
/**
* Sinon.JS 1.8.0, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
/**
* Helps IE run the fake timers. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake timers to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
// Reassign the original functions. Now their writable attribute
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;
/*global sinon*/
/**
* Helps IE run the fake XMLHttpRequest. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake XHR to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function XMLHttpRequest() {}
// Reassign the original function. Now its writable attribute
// should be true. Hackish, I know, but it works.
XMLHttpRequest = sinon.xhr.XMLHttpRequest || undefined;

86
js/npm/node_modules/sinon/pkg/sinon-ie-1.8.1.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
/**
* Sinon.JS 1.8.1, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
/**
* Helps IE run the fake timers. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake timers to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
// Reassign the original functions. Now their writable attribute
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;
/*global sinon*/
/**
* Helps IE run the fake XMLHttpRequest. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake XHR to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function XMLHttpRequest() {}
// Reassign the original function. Now its writable attribute
// should be true. Hackish, I know, but it works.
XMLHttpRequest = sinon.xhr.XMLHttpRequest || undefined;

View File

@ -1,5 +1,5 @@
/**
* Sinon.JS 1.7.3, 2013/06/20
* Sinon.JS 1.8.1, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
@ -49,6 +49,8 @@
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
@ -57,6 +59,8 @@ function Date() {}
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;

View File

@ -1,5 +1,5 @@
/**
* Sinon.JS 1.7.3, 2013/06/20
* Sinon.JS 1.7.3, 2013/10/18
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
@ -44,7 +44,7 @@
* Copyright (c) 2010-2013 Christian Johansen
*/
var sinon = (function (buster) {
var sinon = (function (formatio) {
var div = typeof document != "undefined" && document.createElement("div");
var hasOwn = Object.prototype.hasOwnProperty;
@ -97,26 +97,35 @@ var sinon = (function (buster) {
throw new TypeError("Method wrapper should be function");
}
var wrappedMethod = object[property];
var wrappedMethod = object[property],
error;
if (!isFunction(wrappedMethod)) {
throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
error = new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
property + " as function");
}
if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
error = new TypeError("Attempted to wrap " + property + " which is already wrapped");
}
if (wrappedMethod.calledBefore) {
var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
error = new TypeError("Attempted to wrap " + property + " which is already " + verb);
}
if (error) {
if (wrappedMethod._stack) {
error.stack += '\n--------------\n' + wrappedMethod._stack;
}
throw error;
}
// IE 8 does not support hasOwnProperty on the window object.
var owned = hasOwn.call(object, property);
object[property] = method;
method.displayName = property;
method._stack = (new Error('Stack Trace for original')).stack;
method.restore = function () {
// For prototype properties try to reset by delete first.
@ -185,26 +194,16 @@ var sinon = (function (buster) {
return false;
}
if (aString == "[object Array]") {
if (a.length !== b.length) {
return false;
}
for (var i = 0, l = a.length; i < l; i += 1) {
if (!deepEqual(a[i], b[i])) {
return false;
}
}
return true;
}
if (aString == "[object Date]") {
return a.valueOf() === b.valueOf();
}
var prop, aLength = 0, bLength = 0;
if (aString == "[object Array]" && a.length !== b.length) {
return false;
}
for (prop in a) {
aLength += 1;
@ -353,14 +352,15 @@ var sinon = (function (buster) {
}
};
var isNode = typeof module == "object" && typeof require == "function";
var isNode = typeof module !== "undefined" && module.exports;
if (isNode) {
try {
buster = { format: require("buster-format") };
formatio = require("formatio");
} catch (e) {}
module.exports = sinon;
module.exports.spy = require("./sinon/spy");
module.exports.spyCall = require("./sinon/call");
module.exports.stub = require("./sinon/stub");
module.exports.mock = require("./sinon/mock");
module.exports.collection = require("./sinon/collection");
@ -372,9 +372,8 @@ var sinon = (function (buster) {
module.exports.match = require("./sinon/match");
}
if (buster) {
var formatter = sinon.create(buster.format);
formatter.quoteStrings = false;
if (formatio) {
var formatter = formatio.configure({ quoteStrings: false });
sinon.format = function () {
return formatter.ascii.apply(formatter, arguments);
};
@ -391,7 +390,7 @@ var sinon = (function (buster) {
}
return sinon;
}(typeof buster == "object" && buster));
}(typeof formatio == "object" && formatio));
/*jslint eqeqeq: false, onevar: false*/
/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
@ -483,13 +482,14 @@ if (typeof sinon == "undefined") {
* Copyright (c) 2010-2013 Christian Johansen
*/
if (typeof sinon == "undefined") {
this.sinon = {};
}
sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
// wrapper for global
(function(global) {
if (typeof sinon === "undefined") {
global.sinon = {};
}
sinon.xhr = { XMLHttpRequest: global.XMLHttpRequest };
var xhr = sinon.xhr;
xhr.GlobalXMLHttpRequest = global.XMLHttpRequest;
xhr.GlobalActiveXObject = global.ActiveXObject;
@ -861,10 +861,6 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
this.status = typeof status == "number" ? status : 200;
this.statusText = FakeXMLHttpRequest.statusCodes[this.status];
this.setResponseBody(body || "");
if (typeof this.onload === "function"){
this.onload();
}
}
});
@ -971,9 +967,10 @@ sinon.xhr = { XMLHttpRequest: this.XMLHttpRequest };
};
sinon.FakeXMLHttpRequest = FakeXMLHttpRequest;
})(this);
if (typeof module == "object" && typeof require == "function") {
})(typeof global === "object" ? global : this);
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}
@ -1045,7 +1042,7 @@ sinon.fakeServer = (function () {
if (matchOne(response, this.getHTTPMethod(request), requestUrl)) {
if (typeof response.response == "function") {
var ru = response.url;
var args = [request].concat(!ru ? [] : requestUrl.match(ru).slice(1));
var args = [request].concat(ru && typeof ru.exec == "function" ? ru.exec(requestUrl).slice(1) : []);
return response.response.apply(response, args);
}
@ -1185,7 +1182,7 @@ sinon.fakeServer = (function () {
};
}());
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}
@ -1352,7 +1349,7 @@ if (typeof sinon == "undefined") {
},
firstTimerInRange: function (from, to) {
var timer, smallest, originalTimer;
var timer, smallest = null, originalTimer;
for (var id in this.timeouts) {
if (this.timeouts.hasOwnProperty(id)) {
@ -1360,7 +1357,7 @@ if (typeof sinon == "undefined") {
continue;
}
if (!smallest || this.timeouts[id].callAt < smallest) {
if (smallest === null || this.timeouts[id].callAt < smallest) {
originalTimer = this.timeouts[id];
smallest = this.timeouts[id].callAt;
@ -1536,7 +1533,7 @@ sinon.timers = {
Date: Date
};
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

1719
js/npm/node_modules/sinon/pkg/sinon-server-1.8.0.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1719
js/npm/node_modules/sinon/pkg/sinon-server-1.8.1.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/**
* Sinon.JS 1.7.3, 2013/06/20
* Sinon.JS 1.7.3, 2013/10/18
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
@ -196,7 +196,7 @@ if (typeof sinon == "undefined") {
},
firstTimerInRange: function (from, to) {
var timer, smallest, originalTimer;
var timer, smallest = null, originalTimer;
for (var id in this.timeouts) {
if (this.timeouts.hasOwnProperty(id)) {
@ -204,7 +204,7 @@ if (typeof sinon == "undefined") {
continue;
}
if (!smallest || this.timeouts[id].callAt < smallest) {
if (smallest === null || this.timeouts[id].callAt < smallest) {
originalTimer = this.timeouts[id];
smallest = this.timeouts[id].callAt;
@ -380,6 +380,6 @@ sinon.timers = {
Date: Date
};
if (typeof module == "object" && typeof require == "function") {
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

419
js/npm/node_modules/sinon/pkg/sinon-timers-1.8.0.js generated vendored Normal file
View File

@ -0,0 +1,419 @@
/**
* Sinon.JS 1.8.0, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
/*global module, require, window*/
/**
* Fake timer API
* setTimeout
* setInterval
* clearTimeout
* clearInterval
* tick
* reset
* Date
*
* Inspired by jsUnitMockTimeOut from JsUnit
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
if (typeof sinon == "undefined") {
var sinon = {};
}
(function (global) {
var id = 1;
function addTimer(args, recurring) {
if (args.length === 0) {
throw new Error("Function requires at least 1 parameter");
}
if (typeof args[0] === "undefined") {
throw new Error("Callback must be provided to timer calls");
}
var toId = id++;
var delay = args[1] || 0;
if (!this.timeouts) {
this.timeouts = {};
}
this.timeouts[toId] = {
id: toId,
func: args[0],
callAt: this.now + delay,
invokeArgs: Array.prototype.slice.call(args, 2)
};
if (recurring === true) {
this.timeouts[toId].interval = delay;
}
return toId;
}
function parseTime(str) {
if (!str) {
return 0;
}
var strings = str.split(":");
var l = strings.length, i = l;
var ms = 0, parsed;
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
throw new Error("tick only understands numbers and 'h:m:s'");
}
while (i--) {
parsed = parseInt(strings[i], 10);
if (parsed >= 60) {
throw new Error("Invalid time " + str);
}
ms += parsed * Math.pow(60, (l - i - 1));
}
return ms * 1000;
}
function createObject(object) {
var newObject;
if (Object.create) {
newObject = Object.create(object);
} else {
var F = function () {};
F.prototype = object;
newObject = new F();
}
newObject.Date.clock = newObject;
return newObject;
}
sinon.clock = {
now: 0,
create: function create(now) {
var clock = createObject(this);
if (typeof now == "number") {
clock.now = now;
}
if (!!now && typeof now == "object") {
throw new TypeError("now should be milliseconds since UNIX epoch");
}
return clock;
},
setTimeout: function setTimeout(callback, timeout) {
return addTimer.call(this, arguments, false);
},
clearTimeout: function clearTimeout(timerId) {
if (!this.timeouts) {
this.timeouts = [];
}
if (timerId in this.timeouts) {
delete this.timeouts[timerId];
}
},
setInterval: function setInterval(callback, timeout) {
return addTimer.call(this, arguments, true);
},
clearInterval: function clearInterval(timerId) {
this.clearTimeout(timerId);
},
setImmediate: function setImmediate(callback) {
var passThruArgs = Array.prototype.slice.call(arguments, 1);
return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
},
clearImmediate: function clearImmediate(timerId) {
this.clearTimeout(timerId);
},
tick: function tick(ms) {
ms = typeof ms == "number" ? ms : parseTime(ms);
var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
var timer = this.firstTimerInRange(tickFrom, tickTo);
var firstException;
while (timer && tickFrom <= tickTo) {
if (this.timeouts[timer.id]) {
tickFrom = this.now = timer.callAt;
try {
this.callTimer(timer);
} catch (e) {
firstException = firstException || e;
}
}
timer = this.firstTimerInRange(previous, tickTo);
previous = tickFrom;
}
this.now = tickTo;
if (firstException) {
throw firstException;
}
return this.now;
},
firstTimerInRange: function (from, to) {
var timer, smallest = null, originalTimer;
for (var id in this.timeouts) {
if (this.timeouts.hasOwnProperty(id)) {
if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
continue;
}
if (smallest === null || this.timeouts[id].callAt < smallest) {
originalTimer = this.timeouts[id];
smallest = this.timeouts[id].callAt;
timer = {
func: this.timeouts[id].func,
callAt: this.timeouts[id].callAt,
interval: this.timeouts[id].interval,
id: this.timeouts[id].id,
invokeArgs: this.timeouts[id].invokeArgs
};
}
}
}
return timer || null;
},
callTimer: function (timer) {
if (typeof timer.interval == "number") {
this.timeouts[timer.id].callAt += timer.interval;
} else {
delete this.timeouts[timer.id];
}
try {
if (typeof timer.func == "function") {
timer.func.apply(null, timer.invokeArgs);
} else {
eval(timer.func);
}
} catch (e) {
var exception = e;
}
if (!this.timeouts[timer.id]) {
if (exception) {
throw exception;
}
return;
}
if (exception) {
throw exception;
}
},
reset: function reset() {
this.timeouts = {};
},
Date: (function () {
var NativeDate = Date;
function ClockDate(year, month, date, hour, minute, second, ms) {
// Defensive and verbose to avoid potential harm in passing
// explicit undefined when user does not pass argument
switch (arguments.length) {
case 0:
return new NativeDate(ClockDate.clock.now);
case 1:
return new NativeDate(year);
case 2:
return new NativeDate(year, month);
case 3:
return new NativeDate(year, month, date);
case 4:
return new NativeDate(year, month, date, hour);
case 5:
return new NativeDate(year, month, date, hour, minute);
case 6:
return new NativeDate(year, month, date, hour, minute, second);
default:
return new NativeDate(year, month, date, hour, minute, second, ms);
}
}
return mirrorDateProperties(ClockDate, NativeDate);
}())
};
function mirrorDateProperties(target, source) {
if (source.now) {
target.now = function now() {
return target.clock.now;
};
} else {
delete target.now;
}
if (source.toSource) {
target.toSource = function toSource() {
return source.toSource();
};
} else {
delete target.toSource;
}
target.toString = function toString() {
return source.toString();
};
target.prototype = source.prototype;
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
return target;
}
var methods = ["Date", "setTimeout", "setInterval",
"clearTimeout", "clearInterval"];
if (typeof global.setImmediate !== "undefined") {
methods.push("setImmediate");
}
if (typeof global.clearImmediate !== "undefined") {
methods.push("clearImmediate");
}
function restore() {
var method;
for (var i = 0, l = this.methods.length; i < l; i++) {
method = this.methods[i];
if (global[method].hadOwnProperty) {
global[method] = this["_" + method];
} else {
try {
delete global[method];
} catch (e) {}
}
}
// Prevent multiple executions which will completely remove these props
this.methods = [];
}
function stubGlobal(method, clock) {
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
clock["_" + method] = global[method];
if (method == "Date") {
var date = mirrorDateProperties(clock[method], global[method]);
global[method] = date;
} else {
global[method] = function () {
return clock[method].apply(clock, arguments);
};
for (var prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
global[method][prop] = clock[method][prop];
}
}
}
global[method].clock = clock;
}
sinon.useFakeTimers = function useFakeTimers(now) {
var clock = sinon.clock.create(now);
clock.restore = restore;
clock.methods = Array.prototype.slice.call(arguments,
typeof now == "number" ? 1 : 0);
if (clock.methods.length === 0) {
clock.methods = methods;
}
for (var i = 0, l = clock.methods.length; i < l; i++) {
stubGlobal(clock.methods[i], clock);
}
return clock;
};
}(typeof global != "undefined" && typeof global !== "function" ? global : this));
sinon.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

419
js/npm/node_modules/sinon/pkg/sinon-timers-1.8.1.js generated vendored Normal file
View File

@ -0,0 +1,419 @@
/**
* Sinon.JS 1.8.1, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
/*global module, require, window*/
/**
* Fake timer API
* setTimeout
* setInterval
* clearTimeout
* clearInterval
* tick
* reset
* Date
*
* Inspired by jsUnitMockTimeOut from JsUnit
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
if (typeof sinon == "undefined") {
var sinon = {};
}
(function (global) {
var id = 1;
function addTimer(args, recurring) {
if (args.length === 0) {
throw new Error("Function requires at least 1 parameter");
}
if (typeof args[0] === "undefined") {
throw new Error("Callback must be provided to timer calls");
}
var toId = id++;
var delay = args[1] || 0;
if (!this.timeouts) {
this.timeouts = {};
}
this.timeouts[toId] = {
id: toId,
func: args[0],
callAt: this.now + delay,
invokeArgs: Array.prototype.slice.call(args, 2)
};
if (recurring === true) {
this.timeouts[toId].interval = delay;
}
return toId;
}
function parseTime(str) {
if (!str) {
return 0;
}
var strings = str.split(":");
var l = strings.length, i = l;
var ms = 0, parsed;
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) {
throw new Error("tick only understands numbers and 'h:m:s'");
}
while (i--) {
parsed = parseInt(strings[i], 10);
if (parsed >= 60) {
throw new Error("Invalid time " + str);
}
ms += parsed * Math.pow(60, (l - i - 1));
}
return ms * 1000;
}
function createObject(object) {
var newObject;
if (Object.create) {
newObject = Object.create(object);
} else {
var F = function () {};
F.prototype = object;
newObject = new F();
}
newObject.Date.clock = newObject;
return newObject;
}
sinon.clock = {
now: 0,
create: function create(now) {
var clock = createObject(this);
if (typeof now == "number") {
clock.now = now;
}
if (!!now && typeof now == "object") {
throw new TypeError("now should be milliseconds since UNIX epoch");
}
return clock;
},
setTimeout: function setTimeout(callback, timeout) {
return addTimer.call(this, arguments, false);
},
clearTimeout: function clearTimeout(timerId) {
if (!this.timeouts) {
this.timeouts = [];
}
if (timerId in this.timeouts) {
delete this.timeouts[timerId];
}
},
setInterval: function setInterval(callback, timeout) {
return addTimer.call(this, arguments, true);
},
clearInterval: function clearInterval(timerId) {
this.clearTimeout(timerId);
},
setImmediate: function setImmediate(callback) {
var passThruArgs = Array.prototype.slice.call(arguments, 1);
return addTimer.call(this, [callback, 0].concat(passThruArgs), false);
},
clearImmediate: function clearImmediate(timerId) {
this.clearTimeout(timerId);
},
tick: function tick(ms) {
ms = typeof ms == "number" ? ms : parseTime(ms);
var tickFrom = this.now, tickTo = this.now + ms, previous = this.now;
var timer = this.firstTimerInRange(tickFrom, tickTo);
var firstException;
while (timer && tickFrom <= tickTo) {
if (this.timeouts[timer.id]) {
tickFrom = this.now = timer.callAt;
try {
this.callTimer(timer);
} catch (e) {
firstException = firstException || e;
}
}
timer = this.firstTimerInRange(previous, tickTo);
previous = tickFrom;
}
this.now = tickTo;
if (firstException) {
throw firstException;
}
return this.now;
},
firstTimerInRange: function (from, to) {
var timer, smallest = null, originalTimer;
for (var id in this.timeouts) {
if (this.timeouts.hasOwnProperty(id)) {
if (this.timeouts[id].callAt < from || this.timeouts[id].callAt > to) {
continue;
}
if (smallest === null || this.timeouts[id].callAt < smallest) {
originalTimer = this.timeouts[id];
smallest = this.timeouts[id].callAt;
timer = {
func: this.timeouts[id].func,
callAt: this.timeouts[id].callAt,
interval: this.timeouts[id].interval,
id: this.timeouts[id].id,
invokeArgs: this.timeouts[id].invokeArgs
};
}
}
}
return timer || null;
},
callTimer: function (timer) {
if (typeof timer.interval == "number") {
this.timeouts[timer.id].callAt += timer.interval;
} else {
delete this.timeouts[timer.id];
}
try {
if (typeof timer.func == "function") {
timer.func.apply(null, timer.invokeArgs);
} else {
eval(timer.func);
}
} catch (e) {
var exception = e;
}
if (!this.timeouts[timer.id]) {
if (exception) {
throw exception;
}
return;
}
if (exception) {
throw exception;
}
},
reset: function reset() {
this.timeouts = {};
},
Date: (function () {
var NativeDate = Date;
function ClockDate(year, month, date, hour, minute, second, ms) {
// Defensive and verbose to avoid potential harm in passing
// explicit undefined when user does not pass argument
switch (arguments.length) {
case 0:
return new NativeDate(ClockDate.clock.now);
case 1:
return new NativeDate(year);
case 2:
return new NativeDate(year, month);
case 3:
return new NativeDate(year, month, date);
case 4:
return new NativeDate(year, month, date, hour);
case 5:
return new NativeDate(year, month, date, hour, minute);
case 6:
return new NativeDate(year, month, date, hour, minute, second);
default:
return new NativeDate(year, month, date, hour, minute, second, ms);
}
}
return mirrorDateProperties(ClockDate, NativeDate);
}())
};
function mirrorDateProperties(target, source) {
if (source.now) {
target.now = function now() {
return target.clock.now;
};
} else {
delete target.now;
}
if (source.toSource) {
target.toSource = function toSource() {
return source.toSource();
};
} else {
delete target.toSource;
}
target.toString = function toString() {
return source.toString();
};
target.prototype = source.prototype;
target.parse = source.parse;
target.UTC = source.UTC;
target.prototype.toUTCString = source.prototype.toUTCString;
for (var prop in source) {
if (source.hasOwnProperty(prop)) {
target[prop] = source[prop];
}
}
return target;
}
var methods = ["Date", "setTimeout", "setInterval",
"clearTimeout", "clearInterval"];
if (typeof global.setImmediate !== "undefined") {
methods.push("setImmediate");
}
if (typeof global.clearImmediate !== "undefined") {
methods.push("clearImmediate");
}
function restore() {
var method;
for (var i = 0, l = this.methods.length; i < l; i++) {
method = this.methods[i];
if (global[method].hadOwnProperty) {
global[method] = this["_" + method];
} else {
try {
delete global[method];
} catch (e) {}
}
}
// Prevent multiple executions which will completely remove these props
this.methods = [];
}
function stubGlobal(method, clock) {
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(global, method);
clock["_" + method] = global[method];
if (method == "Date") {
var date = mirrorDateProperties(clock[method], global[method]);
global[method] = date;
} else {
global[method] = function () {
return clock[method].apply(clock, arguments);
};
for (var prop in clock[method]) {
if (clock[method].hasOwnProperty(prop)) {
global[method][prop] = clock[method][prop];
}
}
}
global[method].clock = clock;
}
sinon.useFakeTimers = function useFakeTimers(now) {
var clock = sinon.clock.create(now);
clock.restore = restore;
clock.methods = Array.prototype.slice.call(arguments,
typeof now == "number" ? 1 : 0);
if (clock.methods.length === 0) {
clock.methods = methods;
}
for (var i = 0, l = clock.methods.length; i < l; i++) {
stubGlobal(clock.methods[i], clock);
}
return clock;
};
}(typeof global != "undefined" && typeof global !== "function" ? global : this));
sinon.timers = {
setTimeout: setTimeout,
clearTimeout: clearTimeout,
setImmediate: (typeof setImmediate !== "undefined" ? setImmediate : undefined),
clearImmediate: (typeof clearImmediate !== "undefined" ? clearImmediate: undefined),
setInterval: setInterval,
clearInterval: clearInterval,
Date: Date
};
if (typeof module !== 'undefined' && module.exports) {
module.exports = sinon;
}

View File

@ -1,5 +1,5 @@
/**
* Sinon.JS 1.7.3, 2013/06/20
* Sinon.JS 1.7.3, 2013/10/18
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS

66
js/npm/node_modules/sinon/pkg/sinon-timers-ie-1.8.0.js generated vendored Normal file
View File

@ -0,0 +1,66 @@
/**
* Sinon.JS 1.8.0, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
/**
* Helps IE run the fake timers. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake timers to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
// Reassign the original functions. Now their writable attribute
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;

66
js/npm/node_modules/sinon/pkg/sinon-timers-ie-1.8.1.js generated vendored Normal file
View File

@ -0,0 +1,66 @@
/**
* Sinon.JS 1.8.1, 2014/02/02
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2013, Christian Johansen, christian@cjohansen.no
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of Christian Johansen nor the names of his contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*global sinon, setTimeout, setInterval, clearTimeout, clearInterval, Date*/
/**
* Helps IE run the fake timers. By defining global functions, IE allows
* them to be overwritten at a later point. If these are not defined like
* this, overwriting them will result in anything from an exception to browser
* crash.
*
* If you don't require fake timers to work in IE, don't include this file.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
function setTimeout() {}
function clearTimeout() {}
function setImmediate() {}
function clearImmediate() {}
function setInterval() {}
function clearInterval() {}
function Date() {}
// Reassign the original functions. Now their writable attribute
// should be true. Hackish, I know, but it works.
setTimeout = sinon.timers.setTimeout;
clearTimeout = sinon.timers.clearTimeout;
setImmediate = sinon.timers.setImmediate;
clearImmediate = sinon.timers.clearImmediate;
setInterval = sinon.timers.setInterval;
clearInterval = sinon.timers.clearInterval;
Date = sinon.timers.Date;

1789
js/npm/node_modules/sinon/pkg/sinon.js generated vendored

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ require("../sinon/spy_test.js");
require("../sinon/call_test.js");
require("../sinon/stub_test.js");
require("../sinon/mock_test.js");
require("../sinon/util/fake_timers_test.js");
require("../sinon/collection_test.js");
require("../sinon/sandbox_test.js");
require("../sinon/assert_test.js");
@ -12,6 +11,24 @@ require("../sinon/test_case_test.js");
require("../sinon/match_test.js");
var buster = require("../runner");
var args = process.argv.slice(2);
while (args.length) {
switch (args.shift()) {
case "-h":
case "--help":
console.log("Usage: node test/node/run.js [-u]");
console.log(" -u, --unstable Enable unstable tests");
console.log(" -h, --help This cruft");
process.exit(1);
break;
case "-u":
case "--unstable":
require("../sinon/util/fake_timers_test.js");
break;
}
}
buster.testRunner.onCreate(function (runner) {
runner.on("suite:end", function (results) {
// Reporter will be set up after delay, allow

View File

@ -8,7 +8,7 @@
module.exports = buster.extend(buster, require("buster-test"), {
assertions: require("buster-assertions"),
format: require("buster-format"),
format: require("formatio"),
eventedLogger: require("buster-evented-logger")
});
}

60
js/npm/node_modules/sinon/test/server-clock.html generated vendored Normal file
View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<title>Sinon.JS Unit tests</title>
<link rel="stylesheet" type="text/css" href="../node_modules/buster-test/resources/buster-test.css">
<meta charset="utf-8">
</head>
<body>
<h1>Sinon.JS Unit tests</h1>
<p>
Unfortunately this suite is kinda unstable. Run many times. Should
eventually be fixed.
</p>
<!--
Test framework. Not using pre-built bundle because we don't want
Sinon.JS bundled inside Buster.JS (which it is in the official
distribution).
-->
<script src="../node_modules/buster-core/lib/buster-core.js"></script>
<script src="../node_modules/buster-core/lib/buster-event-emitter.js"></script>
<script src="../node_modules/buster-format/lib/buster-format.js"></script>
<script src="../node_modules/buster-assertions/lib/buster-assertions.js"></script>
<script src="../node_modules/buster-evented-logger/lib/buster-evented-logger.js"></script>
<script src="../node_modules/buster-test/node_modules/when/when.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/test-context.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/test-case.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/test-runner.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/auto-run.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/stack-filter.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/reporters.js"></script>
<script src="../node_modules/buster-test/lib/buster-test/reporters/html.js"></script>
<script src="../node_modules/formatio/node_modules/samsam/lib/samsam.js"></script>
<script src="../node_modules/formatio/lib/formatio.js"></script>
<!-- Custom runner -->
<script src="runner.js"></script>
<!-- Sources -->
<script src="../lib/sinon.js"></script>
<script src="../lib/sinon/match.js"></script>
<script src="../lib/sinon/spy.js"></script>
<script src="../lib/sinon/call.js"></script>
<script src="../lib/sinon/behavior.js"></script>
<script src="../lib/sinon/stub.js"></script>
<script src="../lib/sinon/mock.js"></script>
<script src="../lib/sinon/assert.js"></script>
<script src="../lib/sinon/util/event.js"></script>
<script src="../lib/sinon/util/fake_xml_http_request.js"></script>
<script src="../lib/sinon/util/fake_timers.js"></script>
<script src="../lib/sinon/util/xhr_ie.js"></script>
<script src="../lib/sinon/util/timers_ie.js"></script>
<script src="../lib/sinon/util/fake_server.js"></script>
<script src="../lib/sinon/util/fake_server_with_clock.js"></script>
<script src="../lib/sinon/collection.js"></script>
<script src="../lib/sinon/sandbox.js"></script>
<script src="../lib/sinon/test.js"></script>
<script src="../lib/sinon/test_case.js"></script>
<!-- Tests -->
<script src="sinon/util/fake_server_with_clock_test.js"></script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More