diff --git a/README.md b/README.md index 82ad54b..e423020 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ npm install log4js ## tests -Tests now use [vows](http://vowsjs.org), run with `vows test/logging.js`. I am slowly porting the previous tests from jspec (run those with `node tests.js`), since jspec is no longer maintained. +Tests now use [vows](http://vowsjs.org), run with `vows test/logging.js`. ## usage diff --git a/spec/lib/images/bg.png b/spec/lib/images/bg.png deleted file mode 100644 index 947804f..0000000 Binary files a/spec/lib/images/bg.png and /dev/null differ diff --git a/spec/lib/images/hr.png b/spec/lib/images/hr.png deleted file mode 100644 index 4a94d12..0000000 Binary files a/spec/lib/images/hr.png and /dev/null differ diff --git a/spec/lib/images/loading.gif b/spec/lib/images/loading.gif deleted file mode 100644 index c69e937..0000000 Binary files a/spec/lib/images/loading.gif and /dev/null differ diff --git a/spec/lib/images/sprites.bg.png b/spec/lib/images/sprites.bg.png deleted file mode 100644 index dc8790f..0000000 Binary files a/spec/lib/images/sprites.bg.png and /dev/null differ diff --git a/spec/lib/images/sprites.png b/spec/lib/images/sprites.png deleted file mode 100644 index 010b98e..0000000 Binary files a/spec/lib/images/sprites.png and /dev/null differ diff --git a/spec/lib/images/vr.png b/spec/lib/images/vr.png deleted file mode 100644 index b2e7617..0000000 Binary files a/spec/lib/images/vr.png and /dev/null differ diff --git a/spec/lib/jspec.css b/spec/lib/jspec.css deleted file mode 100644 index 629d41c..0000000 --- a/spec/lib/jspec.css +++ /dev/null @@ -1,149 +0,0 @@ -body.jspec { - margin: 45px 0; - font: 12px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; - background: #efefef url(images/bg.png) top left repeat-x; - text-align: center; -} -#jspec { - margin: 0 auto; - padding-top: 30px; - width: 1008px; - background: url(images/vr.png) top left repeat-y; - text-align: left; -} -#jspec-top { - position: relative; - margin: 0 auto; - width: 1008px; - height: 40px; - background: url(images/sprites.bg.png) top left no-repeat; -} -#jspec-bottom { - margin: 0 auto; - width: 1008px; - height: 15px; - background: url(images/sprites.bg.png) bottom left no-repeat; -} -#jspec .loading { - margin-top: -45px; - width: 1008px; - height: 80px; - background: url(images/loading.gif) 50% 50% no-repeat; -} -#jspec-title { - position: absolute; - top: 15px; - left: 20px; - width: 160px; - font-size: 22px; - font-weight: normal; - background: url(images/sprites.png) 0 -126px no-repeat; - text-align: center; -} -#jspec-title em { - font-size: 10px; - font-style: normal; - color: #BCC8D1; -} -#jspec-report * { - margin: 0; - padding: 0; - background: none; - border: none; -} -#jspec-report { - padding: 15px 40px; - font: 11px "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; - color: #7B8D9B; -} -#jspec-report.has-failures { - padding-bottom: 30px; -} -#jspec-report .hidden { - display: none; -} -#jspec-report .heading { - margin-bottom: 15px; -} -#jspec-report .heading span { - padding-right: 10px; -} -#jspec-report .heading .passes em { - color: #0ea0eb; -} -#jspec-report .heading .failures em { - color: #FA1616; -} -#jspec-report table { - font-size: 11px; - border-collapse: collapse; -} -#jspec-report td { - padding: 8px; - text-indent: 30px; - color: #7B8D9B; -} -#jspec-report tr.body { - display: none; -} -#jspec-report tr.body pre { - margin: 0; - padding: 0 0 5px 25px; -} -#jspec-report tr.even:hover + tr.body, -#jspec-report tr.odd:hover + tr.body { - display: block; -} -#jspec-report tr td:first-child em { - display: block; - clear: both; - font-style: normal; - font-weight: normal; - color: #7B8D9B; -} -#jspec-report tr.even:hover, -#jspec-report tr.odd:hover { - text-shadow: 1px 1px 1px #fff; - background: #F2F5F7; -} -#jspec-report td + td { - padding-right: 0; - width: 15px; -} -#jspec-report td.pass { - background: url(images/sprites.png) 3px -7px no-repeat; -} -#jspec-report td.fail { - background: url(images/sprites.png) 3px -158px no-repeat; - font-weight: bold; - color: #FC0D0D; -} -#jspec-report td.requires-implementation { - background: url(images/sprites.png) 3px -333px no-repeat; -} -#jspec-report tr.description td { - margin-top: 25px; - padding-top: 25px; - font-size: 12px; - font-weight: bold; - text-indent: 0; - color: #1a1a1a; -} -#jspec-report tr.description:first-child td { - border-top: none; -} -#jspec-report .assertion { - display: block; - float: left; - margin: 0 0 0 1px; - padding: 0; - width: 1px; - height: 5px; - background: #7B8D9B; -} -#jspec-report .assertion.failed { - background: red; -} -.jspec-sandbox { - display: none; -} \ No newline at end of file diff --git a/spec/lib/jspec.growl.js b/spec/lib/jspec.growl.js deleted file mode 100644 index a150257..0000000 --- a/spec/lib/jspec.growl.js +++ /dev/null @@ -1,115 +0,0 @@ - -// JSpec - Growl - Copyright TJ Holowaychuk (MIT Licensed) - -;(function(){ - - Growl = { - - // --- Version - - version: '1.0.0', - - /** - * Execute the given _cmd_, returning an array of lines from stdout. - * - * Examples: - * - * Growl.exec('growlnotify', '-m', msg) - * - * @param {string ...} cmd - * @return {array} - * @api public - */ - - exec: function(cmd) { - var lines = [], line - with (JavaImporter(java.lang, java.io)) { - var proccess = Runtime.getRuntime().exec(Array.prototype.slice.call(arguments)) - var stream = new DataInputStream(proccess.getInputStream()) - while (line = stream.readLine()) - lines.push(line + '') - stream.close() - } - return lines - }, - - /** - * Return the extension of the given _path_ or null. - * - * @param {string} path - * @return {string} - * @api private - */ - - extname: function(path) { - return path.lastIndexOf('.') != -1 ? - path.slice(path.lastIndexOf('.') + 1, path.length) : - null - }, - - /** - * Version of the 'growlnotify' binary. - * - * @return {string} - * @api private - */ - - binVersion: function() { - try { return this.exec('growlnotify', '-v')[0].split(' ')[1] } catch (e) {} - }, - - /** - * Send growl notification _msg_ with _options_. - * - * Options: - * - * - title Notification title - * - sticky Make the notification stick (defaults to false) - * - name Application name (defaults to growlnotify) - * - image - * - path to an icon sets --iconpath - * - path to an image sets --image - * - capitalized word sets --appIcon - * - filename uses extname as --icon - * - otherwise treated as --icon - * - * Examples: - * - * Growl.notify('New email') - * Growl.notify('5 new emails', { title: 'Thunderbird' }) - * - * @param {string} msg - * @param {options} hash - * @api public - */ - - notify: function(msg, options) { - options = options || {} - var args = ['growlnotify', '-m', msg] - if (!this.binVersion()) throw new Error('growlnotify executable is required') - if (image = options.image) { - var flag, ext = this.extname(image) - flag = flag || ext == 'icns' && 'iconpath' - flag = flag || /^[A-Z]/.test(image) && 'appIcon' - flag = flag || /^png|gif|jpe?g$/.test(ext) && 'image' - flag = flag || ext && (image = ext) && 'icon' - flag = flag || 'icon' - args.push('--' + flag, image) - } - if (options.sticky) args.push('--sticky') - if (options.name) args.push('--name', options.name) - if (options.title) args.push(options.title) - this.exec.apply(this, args) - } - } - - JSpec.include({ - name: 'Growl', - reporting: function(options){ - var stats = JSpec.stats - if (stats.failures) Growl.notify('failed ' + stats.failures + ' assertions', { title: 'JSpec'}) - else Growl.notify('passed ' + stats.passes + ' assertions', { title: 'JSpec' }) - } - }) - -})() \ No newline at end of file diff --git a/spec/lib/jspec.jquery.js b/spec/lib/jspec.jquery.js deleted file mode 100644 index 3c1f784..0000000 --- a/spec/lib/jspec.jquery.js +++ /dev/null @@ -1,71 +0,0 @@ - -// JSpec - jQuery - Copyright TJ Holowaychuk (MIT Licensed) - -JSpec -.requires('jQuery', 'when using jspec.jquery.js') -.include({ - name: 'jQuery', - - // --- Initialize - - init : function() { - jQuery.ajaxSetup({ async: false }) - }, - - // --- Utilities - - utilities : { - element: jQuery, - elements: jQuery, - sandbox : function() { - return jQuery('
') - } - }, - - // --- Matchers - - matchers : { - have_tag : "jQuery(expected, actual).length == 1", - have_one : "alias have_tag", - have_tags : "jQuery(expected, actual).length > 1", - have_many : "alias have_tags", - have_child : "jQuery(actual).children(expected).length == 1", - have_children : "jQuery(actual).children(expected).length > 1", - have_text : "jQuery(actual).text() == expected", - have_value : "jQuery(actual).val() == expected", - be_enabled : "!jQuery(actual).attr('disabled')", - have_class : "jQuery(actual).hasClass(expected)", - - be_visible : function(actual) { - return jQuery(actual).css('display') != 'none' && - jQuery(actual).css('visibility') != 'hidden' && - jQuery(actual).attr('type') != 'hidden' - }, - - be_hidden : function(actual) { - return !JSpec.does(actual, 'be_visible') - }, - - have_classes : function(actual) { - return !JSpec.any(JSpec.toArray(arguments, 1), function(arg){ - return !JSpec.does(actual, 'have_class', arg) - }) - }, - - have_attr : function(actual, attr, value) { - return value ? jQuery(actual).attr(attr) == value: - jQuery(actual).attr(attr) - }, - - 'be disabled selected checked' : function(attr) { - return 'jQuery(actual).attr("' + attr + '")' - }, - - 'have type id title alt href src sel rev name target' : function(attr) { - return function(actual, value) { - return JSpec.does(actual, 'have_attr', attr, value) - } - } - } -}) - diff --git a/spec/lib/jspec.js b/spec/lib/jspec.js deleted file mode 100644 index 742987c..0000000 --- a/spec/lib/jspec.js +++ /dev/null @@ -1,1773 +0,0 @@ - -// JSpec - Core - Copyright TJ Holowaychuk (MIT Licensed) - -;(function(){ - - JSpec = { - version : '3.1.3', - assert : true, - cache : {}, - suites : [], - modules : [], - allSuites : [], - matchers : {}, - stubbed : [], - options : {}, - request : 'XMLHttpRequest' in this ? XMLHttpRequest : null, - stats : { specs: 0, assertions: 0, failures: 0, passes: 0, specsFinished: 0, suitesFinished: 0 }, - - /** - * Default context in which bodies are evaluated. - * - * Replace context simply by setting JSpec.context - * to your own like below: - * - * JSpec.context = { foo : 'bar' } - * - * Contexts can be changed within any body, this can be useful - * in order to provide specific helper methods to specific suites. - * - * To reset (usually in after hook) simply set to null like below: - * - * JSpec.context = null - * - */ - - defaultContext : { - - /** - * Return an object used for proxy assertions. - * This object is used to indicate that an object - * should be an instance of _object_, not the constructor - * itself. - * - * @param {function} constructor - * @return {hash} - * @api public - */ - - an_instance_of : function(constructor) { - return { an_instance_of : constructor } - }, - - /** - * Load fixture at _path_. - * - * Fixtures are resolved as: - * - * - - * - .html - * - * @param {string} path - * @return {string} - * @api public - */ - - fixture : function(path) { - if (JSpec.cache[path]) return JSpec.cache[path] - return JSpec.cache[path] = - JSpec.tryLoading(JSpec.options.fixturePath + '/' + path) || - JSpec.tryLoading(JSpec.options.fixturePath + '/' + path + '.html') - } - }, - - // --- Objects - - reporters : { - - /** - * Report to server. - * - * Options: - * - uri specific uri to report to. - * - verbose weither or not to output messages - * - failuresOnly output failure messages only - * - * @api public - */ - - Server : function(results, options) { - var uri = options.uri || 'http://' + window.location.host + '/results' - JSpec.post(uri, { - stats: JSpec.stats, - options: options, - results: map(results.allSuites, function(suite) { - if (suite.hasSpecs()) - return { - description: suite.description, - specs: map(suite.specs, function(spec) { - return { - description: spec.description, - message: !spec.passed() ? spec.failure().message : null, - status: spec.requiresImplementation() ? 'pending' : - spec.passed() ? 'pass' : - 'fail', - assertions: map(spec.assertions, function(assertion){ - return { - passed: assertion.passed - } - }) - } - }) - } - }) - }) - if ('close' in main) main.close() - }, - - /** - * Default reporter, outputting to the DOM. - * - * Options: - * - reportToId id of element to output reports to, defaults to 'jspec' - * - failuresOnly displays only suites with failing specs - * - * @api public - */ - - DOM : function(results, options) { - var id = option('reportToId') || 'jspec' - var report = document.getElementById(id) - var failuresOnly = option('failuresOnly') - var classes = results.stats.failures ? 'has-failures' : '' - if (!report) throw 'JSpec requires the element #' + id + ' to output its reports' - - function bodyContents(body) { - return JSpec. - escape(JSpec.contentsOf(body)). - replace(/^ */gm, function(a){ return (new Array(Math.round(a.length / 3))).join(' ') }). - replace(/\r\n|\r|\n/gm, '
') - } - - report.innerHTML = '
\ - Passes: ' + results.stats.passes + ' \ - Failures: ' + results.stats.failures + ' \ - Duration: ' + results.duration + ' ms \ -
' + map(results.allSuites, function(suite) { - var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran - if (displaySuite && suite.hasSpecs()) - return '' + - map(suite.specs, function(i, spec) { - return '' + - (spec.requiresImplementation() ? - '' : - (spec.passed() && !failuresOnly) ? - '' : - !spec.passed() ? - '' : - '') + - '' - }).join('') + '' - }).join('') + '
' + escape(suite.description) + '
' + escape(spec.description) + '' + escape(spec.description)+ '' + spec.assertionsGraph() + '' + escape(spec.description) + - map(spec.failures(), function(a){ return '' + escape(a.message) + '' }).join('') + - '' + spec.assertionsGraph() + '
' + bodyContents(spec.body) + '
' - }, - - /** - * Terminal reporter. - * - * @api public - */ - - Terminal : function(results, options) { - failuresOnly = option('failuresOnly') - print(color("\n Passes: ", 'bold') + color(results.stats.passes, 'green') + - color(" Failures: ", 'bold') + color(results.stats.failures, 'red') + - color(" Duration: ", 'bold') + color(results.duration, 'green') + " ms \n") - - function indent(string) { - return string.replace(/^(.)/gm, ' $1') - } - - each(results.allSuites, function(suite) { - var displaySuite = failuresOnly ? suite.ran && !suite.passed() : suite.ran - if (displaySuite && suite.hasSpecs()) { - print(color(' ' + suite.description, 'bold')) - each(suite.specs, function(spec){ - var assertionsGraph = inject(spec.assertions, '', function(graph, assertion){ - return graph + color('.', assertion.passed ? 'green' : 'red') - }) - if (spec.requiresImplementation()) - print(color(' ' + spec.description, 'blue') + assertionsGraph) - else if (spec.passed() && !failuresOnly) - print(color(' ' + spec.description, 'green') + assertionsGraph) - else if (!spec.passed()) - print(color(' ' + spec.description, 'red') + assertionsGraph + - "\n" + indent(map(spec.failures(), function(a){ return a.message }).join("\n")) + "\n") - }) - print("") - } - }) - - quit(results.stats.failures) - }, - - /** - * Console reporter. - * - * @api public - */ - - Console : function(results, options) { - console.log('') - console.log('Passes: ' + results.stats.passes + ' Failures: ' + results.stats.failures) - each(results.allSuites, function(suite) { - if (suite.ran) { - console.group(suite.description) - each(suite.specs, function(spec){ - var assertionCount = spec.assertions.length + ':' - if (spec.requiresImplementation()) - console.warn(spec.description) - else if (spec.passed()) - console.log(assertionCount + ' ' + spec.description) - else - console.error(assertionCount + ' ' + spec.description + ', ' + spec.failure().message) - }) - console.groupEnd() - } - }) - } - }, - - Assertion : function(matcher, actual, expected, negate) { - extend(this, { - message: '', - passed: false, - actual: actual, - negate: negate, - matcher: matcher, - expected: expected, - - // Report assertion results - - report : function() { - if (JSpec.assert) - this.passed ? JSpec.stats.passes++ : JSpec.stats.failures++ - return this - }, - - // Run the assertion - - run : function() { - // TODO: remove unshifting - expected.unshift(actual) - this.result = matcher.match.apply(this, expected) - this.passed = negate ? !this.result : this.result - if (!this.passed) this.message = matcher.message.call(this, actual, expected, negate, matcher.name) - return this - } - }) - }, - - ProxyAssertion : function(object, method, times, negate) { - var self = this - var old = object[method] - - // Proxy - - object[method] = function(){ - args = toArray(arguments) - result = old.apply(object, args) - self.calls.push({ args : args, result : result }) - return result - } - - // Times - - this.times = { - once : 1, - twice : 2 - }[times] || times || 1 - - extend(this, { - calls: [], - message: '', - defer: true, - passed: false, - negate: negate, - object: object, - method: method, - - // Proxy return value - - and_return : function(result) { - this.expectedResult = result - return this - }, - - // Proxy arguments passed - - with_args : function() { - this.expectedArgs = toArray(arguments) - return this - }, - - // Check if any calls have failing results - - anyResultsFail : function() { - return any(this.calls, function(call){ - return self.expectedResult.an_instance_of ? - call.result.constructor != self.expectedResult.an_instance_of: - !equal(self.expectedResult, call.result) - }) - }, - - // Check if any calls have passing results - - anyResultsPass : function() { - return any(this.calls, function(call){ - return self.expectedResult.an_instance_of ? - call.result.constructor == self.expectedResult.an_instance_of: - equal(self.expectedResult, call.result) - }) - }, - - // Return the passing result - - passingResult : function() { - return this.anyResultsPass().result - }, - - // Return the failing result - - failingResult : function() { - return this.anyResultsFail().result - }, - - // Check if any arguments fail - - anyArgsFail : function() { - return any(this.calls, function(call){ - return any(self.expectedArgs, function(i, arg){ - if (arg == null) return call.args[i] == null - return arg.an_instance_of ? - call.args[i].constructor != arg.an_instance_of: - !equal(arg, call.args[i]) - - }) - }) - }, - - // Check if any arguments pass - - anyArgsPass : function() { - return any(this.calls, function(call){ - return any(self.expectedArgs, function(i, arg){ - return arg.an_instance_of ? - call.args[i].constructor == arg.an_instance_of: - equal(arg, call.args[i]) - - }) - }) - }, - - // Return the passing args - - passingArgs : function() { - return this.anyArgsPass().args - }, - - // Return the failing args - - failingArgs : function() { - return this.anyArgsFail().args - }, - - // Report assertion results - - report : function() { - if (JSpec.assert) - this.passed ? ++JSpec.stats.passes : ++JSpec.stats.failures - return this - }, - - // Run the assertion - - run : function() { - var methodString = 'expected ' + object.toString() + '.' + method + '()' + (negate ? ' not' : '' ) - - function times(n) { - return n > 2 ? n + ' times' : { 1: 'once', 2: 'twice' }[n] - } - - if (this.expectedResult != null && (negate ? this.anyResultsPass() : this.anyResultsFail())) - this.message = methodString + ' to return ' + puts(this.expectedResult) + - ' but ' + (negate ? 'it did' : 'got ' + puts(this.failingResult())) - - if (this.expectedArgs && (negate ? !this.expectedResult && this.anyArgsPass() : this.anyArgsFail())) - this.message = methodString + ' to be called with ' + puts.apply(this, this.expectedArgs) + - ' but was' + (negate ? '' : ' called with ' + puts.apply(this, this.failingArgs())) - - if (negate ? !this.expectedResult && !this.expectedArgs && this.calls.length >= this.times : this.calls.length != this.times) - this.message = methodString + ' to be called ' + times(this.times) + - ', but ' + (this.calls.length == 0 ? ' was not called' : ' was called ' + times(this.calls.length)) - - if (!this.message.length) - this.passed = true - - return this - } - }) - }, - - /** - * Specification Suite block object. - * - * @param {string} description - * @param {function} body - * @api private - */ - - Suite : function(description, body) { - var self = this - extend(this, { - body: body, - description: description, - suites: [], - specs: [], - ran: false, - hooks: { 'before' : [], 'after' : [], 'before_each' : [], 'after_each' : [] }, - - // Add a spec to the suite - - addSpec : function(description, body) { - var spec = new JSpec.Spec(description, body) - this.specs.push(spec) - JSpec.stats.specs++ // TODO: abstract - spec.suite = this - }, - - // Add a hook to the suite - - addHook : function(hook, body) { - this.hooks[hook].push(body) - }, - - // Add a nested suite - - addSuite : function(description, body) { - var suite = new JSpec.Suite(description, body) - JSpec.allSuites.push(suite) - suite.name = suite.description - suite.description = this.description + ' ' + suite.description - this.suites.push(suite) - suite.suite = this - }, - - // Invoke a hook in context to this suite - - hook : function(hook) { - if (this.suite) this.suite.hook(hook) - each(this.hooks[hook], function(body) { - JSpec.evalBody(body, "Error in hook '" + hook + "', suite '" + self.description + "': ") - }) - }, - - // Check if nested suites are present - - hasSuites : function() { - return this.suites.length - }, - - // Check if this suite has specs - - hasSpecs : function() { - return this.specs.length - }, - - // Check if the entire suite passed - - passed : function() { - return !any(this.specs, function(spec){ - return !spec.passed() - }) - } - }) - }, - - /** - * Specification block object. - * - * @param {string} description - * @param {function} body - * @api private - */ - - Spec : function(description, body) { - extend(this, { - body: body, - description: description, - assertions: [], - - // Add passing assertion - - pass : function(message) { - this.assertions.push({ passed: true, message: message }) - if (JSpec.assert) ++JSpec.stats.passes - }, - - // Add failing assertion - - fail : function(message) { - this.assertions.push({ passed: false, message: message }) - if (JSpec.assert) ++JSpec.stats.failures - }, - - // Run deferred assertions - - runDeferredAssertions : function() { - each(this.assertions, function(assertion){ - if (assertion.defer) assertion.run().report(), hook('afterAssertion', assertion) - }) - }, - - // Find first failing assertion - - failure : function() { - return find(this.assertions, function(assertion){ - return !assertion.passed - }) - }, - - // Find all failing assertions - - failures : function() { - return select(this.assertions, function(assertion){ - return !assertion.passed - }) - }, - - // Weither or not the spec passed - - passed : function() { - return !this.failure() - }, - - // Weither or not the spec requires implementation (no assertions) - - requiresImplementation : function() { - return this.assertions.length == 0 - }, - - // Sprite based assertions graph - - assertionsGraph : function() { - return map(this.assertions, function(assertion){ - return '' - }).join('') - } - }) - }, - - Module : function(methods) { - extend(this, methods) - }, - - JSON : { - - /** - * Generic sequences. - */ - - meta : { - '\b' : '\\b', - '\t' : '\\t', - '\n' : '\\n', - '\f' : '\\f', - '\r' : '\\r', - '"' : '\\"', - '\\' : '\\\\' - }, - - /** - * Escapable sequences. - */ - - escapable : /[\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, - - /** - * JSON encode _object_. - * - * @param {mixed} object - * @return {string} - * @api private - */ - - encode : function(object) { - var self = this - if (object == undefined || object == null) return 'null' - if (object === true) return 'true' - if (object === false) return 'false' - switch (typeof object) { - case 'number': return object - case 'string': return this.escapable.test(object) ? - '"' + object.replace(this.escapable, function (a) { - return typeof self.meta[a] === 'string' ? self.meta[a] : - '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4) - }) + '"' : - '"' + object + '"' - case 'object': - if (object.constructor == Array) - return '[' + map(object, function(val){ - return self.encode(val) - }).join(', ') + ']' - else if (object) - return '{' + map(object, function(key, val){ - return self.encode(key) + ':' + self.encode(val) - }).join(', ') + '}' - } - return 'null' - } - }, - - // --- DSLs - - DSLs : { - snake : { - expect : function(actual){ - return JSpec.expect(actual) - }, - - describe : function(description, body) { - return JSpec.currentSuite.addSuite(description, body) - }, - - it : function(description, body) { - return JSpec.currentSuite.addSpec(description, body) - }, - - before : function(body) { - return JSpec.currentSuite.addHook('before', body) - }, - - after : function(body) { - return JSpec.currentSuite.addHook('after', body) - }, - - before_each : function(body) { - return JSpec.currentSuite.addHook('before_each', body) - }, - - after_each : function(body) { - return JSpec.currentSuite.addHook('after_each', body) - }, - - should_behave_like : function(description) { - return JSpec.shareBehaviorsOf(description) - } - } - }, - - // --- Methods - - /** - * Check if _value_ is 'stop'. For use as a - * utility callback function. - * - * @param {mixed} value - * @return {bool} - * @api public - */ - - haveStopped : function(value) { - return value === 'stop' - }, - - /** - * Include _object_ which may be a hash or Module instance. - * - * @param {hash, Module} object - * @return {JSpec} - * @api public - */ - - include : function(object) { - var module = object.constructor == JSpec.Module ? object : new JSpec.Module(object) - this.modules.push(module) - if ('init' in module) module.init() - if ('utilities' in module) extend(this.defaultContext, module.utilities) - if ('matchers' in module) this.addMatchers(module.matchers) - if ('reporters' in module) extend(this.reporters, module.reporters) - if ('DSLs' in module) - each(module.DSLs, function(name, methods){ - JSpec.DSLs[name] = JSpec.DSLs[name] || {} - extend(JSpec.DSLs[name], methods) - }) - return this - }, - - /** - * Add a module hook _name_, which is immediately - * called per module with the _args_ given. An array of - * hook return values is returned. - * - * @param {name} string - * @param {...} args - * @return {array} - * @api private - */ - - hook : function(name, args) { - args = toArray(arguments, 1) - return inject(JSpec.modules, [], function(results, module){ - if (typeof module[name] == 'function') - results.push(JSpec.evalHook(module, name, args)) - }) - }, - - /** - * Eval _module_ hook _name_ with _args_. Evaluates in context - * to the module itself, JSpec, and JSpec.context. - * - * @param {Module} module - * @param {string} name - * @param {array} args - * @return {mixed} - * @api private - */ - - evalHook : function(module, name, args) { - hook('evaluatingHookBody', module, name) - try { return module[name].apply(module, args) } - catch(e) { error('Error in hook ' + module.name + '.' + name + ': ', e) } - }, - - /** - * Same as hook() however accepts only one _arg_ which is - * considered immutable. This function passes the arg - * to the first module, then passes the return value of the last - * module called, to the following module. - * - * @param {string} name - * @param {mixed} arg - * @return {mixed} - * @api private - */ - - hookImmutable : function(name, arg) { - return inject(JSpec.modules, arg, function(result, module){ - if (typeof module[name] == 'function') - return JSpec.evalHook(module, name, [result]) - }) - }, - - /** - * Find a suite by its description or name. - * - * @param {string} description - * @return {Suite} - * @api private - */ - - findSuite : function(description) { - return find(this.allSuites, function(suite){ - return suite.name == description || suite.description == description - }) - }, - - /** - * Share behaviors (specs) of the given suite with - * the current suite. - * - * @param {string} description - * @api public - */ - - shareBehaviorsOf : function(description) { - if (suite = this.findSuite(description)) this.copySpecs(suite, this.currentSuite) - else throw 'failed to share behaviors. ' + puts(description) + ' is not a valid Suite name' - }, - - /** - * Copy specs from one suite to another. - * - * @param {Suite} fromSuite - * @param {Suite} toSuite - * @api public - */ - - copySpecs : function(fromSuite, toSuite) { - each(fromSuite.specs, function(spec){ - spec.assertions = [] - toSuite.specs.push(spec) - }) - }, - - /** - * Convert arguments to an array. - * - * @param {object} arguments - * @param {int} offset - * @return {array} - * @api public - */ - - toArray : function(arguments, offset) { - return Array.prototype.slice.call(arguments, offset || 0) - }, - - /** - * Return ANSI-escaped colored string. - * - * @param {string} string - * @param {string} color - * @return {string} - * @api public - */ - - color : function(string, color) { - return "\u001B[" + { - bold : 1, - black : 30, - red : 31, - green : 32, - yellow : 33, - blue : 34, - magenta : 35, - cyan : 36, - white : 37 - }[color] + 'm' + string + "\u001B[0m" - }, - - /** - * Default matcher message callback. - * - * @api private - */ - - defaultMatcherMessage : function(actual, expected, negate, name) { - return 'expected ' + puts(actual) + ' to ' + - (negate ? 'not ' : '') + - name.replace(/_/g, ' ') + - ' ' + (expected.length > 1 ? - puts.apply(this, expected.slice(1)) : - '') - }, - - /** - * Normalize a matcher message. - * - * When no messge callback is present the defaultMatcherMessage - * will be assigned, will suffice for most matchers. - * - * @param {hash} matcher - * @return {hash} - * @api public - */ - - normalizeMatcherMessage : function(matcher) { - if (typeof matcher.message != 'function') - matcher.message = this.defaultMatcherMessage - return matcher - }, - - /** - * Normalize a matcher body - * - * This process allows the following conversions until - * the matcher is in its final normalized hash state. - * - * - '==' becomes 'actual == expected' - * - 'actual == expected' becomes 'return actual == expected' - * - function(actual, expected) { return actual == expected } becomes - * { match : function(actual, expected) { return actual == expected }} - * - * @param {mixed} body - * @return {hash} - * @api public - */ - - normalizeMatcherBody : function(body) { - switch (body.constructor) { - case String: - if (captures = body.match(/^alias (\w+)/)) return JSpec.matchers[last(captures)] - if (body.length < 4) body = 'actual ' + body + ' expected' - return { match: function(actual, expected) { return eval(body) }} - - case Function: - return { match: body } - - default: - return body - } - }, - - /** - * Get option value. This method first checks if - * the option key has been set via the query string, - * otherwise returning the options hash value. - * - * @param {string} key - * @return {mixed} - * @api public - */ - - option : function(key) { - return (value = query(key)) !== null ? value : - JSpec.options[key] || null - }, - - /** - * Check if object _a_, is equal to object _b_. - * - * @param {object} a - * @param {object} b - * @return {bool} - * @api private - */ - - equal: function(a, b) { - if (typeof a != typeof b) return - if (a === b) return true - if (a instanceof RegExp) - return a.toString() === b.toString() - if (a instanceof Date) - return Number(a) === Number(b) - if (typeof a != 'object') return - if (a.length !== undefined) - if (a.length !== b.length) return - else - for (var i = 0, len = a.length; i < len; ++i) - if (!equal(a[i], b[i])) - return - for (var key in a) - if (!equal(a[key], b[key])) - return - return true - }, - - /** - * Return last element of an array. - * - * @param {array} array - * @return {object} - * @api public - */ - - last : function(array) { - return array[array.length - 1] - }, - - /** - * Convert object(s) to a print-friend string. - * - * @param {...} object - * @return {string} - * @api public - */ - - puts : function(object) { - if (arguments.length > 1) - return map(toArray(arguments), function(arg){ - return puts(arg) - }).join(', ') - if (object === undefined) return 'undefined' - if (object === null) return 'null' - if (object === true) return 'true' - if (object === false) return 'false' - if (object.an_instance_of) return 'an instance of ' + object.an_instance_of.name - if (object.jquery && object.selector.length > 0) return 'selector ' + puts(object.selector) - if (object.jquery) return object.get(0).outerHTML - if (object.nodeName) return object.outerHTML - switch (object.constructor) { - case Function: return object.name || object - case String: - return '"' + object - .replace(/"/g, '\\"') - .replace(/\n/g, '\\n') - .replace(/\t/g, '\\t') - + '"' - case Array: - return inject(object, '[', function(b, v){ - return b + ', ' + puts(v) - }).replace('[,', '[') + ' ]' - case Object: - object.__hit__ = true - return inject(object, '{', function(b, k, v) { - if (k == '__hit__') return b - return b + ', ' + k + ': ' + (v && v.__hit__ ? '' : puts(v)) - }).replace('{,', '{') + ' }' - default: - return object.toString() - } - }, - - /** - * Escape HTML. - * - * @param {string} html - * @return {string} - * @api public - */ - - escape : function(html) { - return html.toString() - .replace(/&/gmi, '&') - .replace(/"/gmi, '"') - .replace(/>/gmi, '>') - .replace(/ current) while (++current <= end) values.push(current) - else while (--current >= end) values.push(current) - return '[' + values + ']' - }, - - /** - * Report on the results. - * - * @api public - */ - - report : function() { - this.duration = Number(new Date) - this.start - hook('reporting', JSpec.options) - new (JSpec.options.reporter || JSpec.reporters.DOM)(JSpec, JSpec.options) - }, - - /** - * Run the spec suites. Options are merged - * with JSpec options when present. - * - * @param {hash} options - * @return {JSpec} - * @api public - */ - - run : function(options) { - if (any(hook('running'), haveStopped)) return this - if (options) extend(this.options, options) - this.start = Number(new Date) - each(this.suites, function(suite) { JSpec.runSuite(suite) }) - return this - }, - - /** - * Run a suite. - * - * @param {Suite} suite - * @api public - */ - - runSuite : function(suite) { - this.currentSuite = suite - this.evalBody(suite.body) - suite.ran = true - hook('beforeSuite', suite), suite.hook('before') - each(suite.specs, function(spec) { - hook('beforeSpec', spec) - suite.hook('before_each') - JSpec.runSpec(spec) - hook('afterSpec', spec) - suite.hook('after_each') - }) - if (suite.hasSuites()) { - each(suite.suites, function(suite) { - JSpec.runSuite(suite) - }) - } - hook('afterSuite', suite), suite.hook('after') - this.stats.suitesFinished++ - }, - - /** - * Report a failure for the current spec. - * - * @param {string} message - * @api public - */ - - fail : function(message) { - JSpec.currentSpec.fail(message) - }, - - /** - * Report a passing assertion for the current spec. - * - * @param {string} message - * @api public - */ - - pass : function(message) { - JSpec.currentSpec.pass(message) - }, - - /** - * Run a spec. - * - * @param {Spec} spec - * @api public - */ - - runSpec : function(spec) { - this.currentSpec = spec - try { this.evalBody(spec.body) } - catch (e) { fail(e) } - spec.runDeferredAssertions() - destub() - this.stats.specsFinished++ - this.stats.assertions += spec.assertions.length - }, - - /** - * Require a dependency, with optional message. - * - * @param {string} dependency - * @param {string} message (optional) - * @return {JSpec} - * @api public - */ - - requires : function(dependency, message) { - hook('requiring', dependency, message) - try { eval(dependency) } - catch (e) { throw 'JSpec depends on ' + dependency + ' ' + message } - return this - }, - - /** - * Query against the current query strings keys - * or the queryString specified. - * - * @param {string} key - * @param {string} queryString - * @return {string, null} - * @api private - */ - - query : function(key, queryString) { - var queryString = (queryString || (main.location ? main.location.search : null) || '').substring(1) - return inject(queryString.split('&'), null, function(value, pair){ - parts = pair.split('=') - return parts[0] == key ? parts[1].replace(/%20|\+/gmi, ' ') : value - }) - }, - - /** - * Throw a JSpec related error. - * - * @param {string} message - * @param {Exception} e - * @api public - */ - - error : function(message, e) { - throw (message ? message : '') + e.toString() + - (e.line ? ' near line ' + e.line : '') - }, - - /** - * Ad-hoc POST request for JSpec server usage. - * - * @param {string} uri - * @param {string} data - * @api private - */ - - post : function(uri, data) { - if (any(hook('posting', uri, data), haveStopped)) return - var request = this.xhr() - request.open('POST', uri, false) - request.setRequestHeader('Content-Type', 'application/json') - request.send(JSpec.JSON.encode(data)) - }, - - /** - * Instantiate an XMLHttpRequest. - * - * Here we utilize IE's lame ActiveXObjects first which - * allow IE access serve files via the file: protocol, otherwise - * we then default to XMLHttpRequest. - * - * @return {XMLHttpRequest, ActiveXObject} - * @api private - */ - - xhr : function() { - return this.ieXhr() || new JSpec.request - }, - - /** - * Return Microsoft piece of crap ActiveXObject. - * - * @return {ActiveXObject} - * @api public - */ - - ieXhr : function() { - function object(str) { - try { return new ActiveXObject(str) } catch(e) {} - } - return object('Msxml2.XMLHTTP.6.0') || - object('Msxml2.XMLHTTP.3.0') || - object('Msxml2.XMLHTTP') || - object('Microsoft.XMLHTTP') - }, - - /** - * Check for HTTP request support. - * - * @return {bool} - * @api private - */ - - hasXhr : function() { - return JSpec.request || 'ActiveXObject' in main - }, - - /** - * Try loading _file_ returning the contents - * string or null. Chain to locate / read a file. - * - * @param {string} file - * @return {string} - * @api public - */ - - tryLoading : function(file) { - try { return JSpec.load(file) } catch (e) {} - }, - - /** - * Load a _file_'s contents. - * - * @param {string} file - * @param {function} callback - * @return {string} - * @api public - */ - - load : function(file, callback) { - if (any(hook('loading', file), haveStopped)) return - if ('readFile' in main) - return readFile(file) - else if (this.hasXhr()) { - var request = this.xhr() - request.open('GET', file, false) - request.send(null) - if (request.readyState == 4 && - (request.status == 0 || - request.status.toString().charAt(0) == 2)) - return request.responseText - } - else - error("failed to load `" + file + "'") - }, - - /** - * Load, pre-process, and evaluate a file. - * - * @param {string} file - * @param {JSpec} - * @api public - */ - - exec : function(file) { - if (any(hook('executing', file), haveStopped)) return this - eval('with (JSpec){' + this.preprocess(this.load(file)) + '}') - return this - } - } - - // --- Utility functions - - var main = this - var find = JSpec.any - var utils = 'haveStopped stub hookImmutable hook destub map any last pass fail range each option inject select \ - error escape extend puts query strip color does addMatchers callIterator toArray equal'.split(/\s+/) - while (utils.length) eval('var ' + utils[0] + ' = JSpec.' + utils.shift()) - if (!main.setTimeout) main.setTimeout = function(callback){ callback() } - - // --- Matchers - - addMatchers({ - equal : "===", - eql : "equal(actual, expected)", - be : "alias equal", - be_greater_than : ">", - be_less_than : "<", - be_at_least : ">=", - be_at_most : "<=", - be_a : "actual.constructor == expected", - be_an : "alias be_a", - be_an_instance_of : "actual instanceof expected", - be_null : "actual == null", - be_true : "actual == true", - be_false : "actual == false", - be_undefined : "typeof actual == 'undefined'", - be_type : "typeof actual == expected", - match : "typeof actual == 'string' ? actual.match(expected) : false", - respond_to : "typeof actual[expected] == 'function'", - have_length : "actual.length == expected", - be_within : "actual >= expected[0] && actual <= last(expected)", - have_length_within : "actual.length >= expected[0] && actual.length <= last(expected)", - - receive : { defer : true, match : function(actual, method, times) { - proxy = new JSpec.ProxyAssertion(actual, method, times, this.negate) - JSpec.currentSpec.assertions.push(proxy) - return proxy - }}, - - be_empty : function(actual) { - if (actual.constructor == Object && actual.length == undefined) - for (var key in actual) - return false; - return !actual.length - }, - - include : function(actual) { - for (state = true, i = 1; i < arguments.length; i++) { - arg = arguments[i] - switch (actual.constructor) { - case String: - case Number: - case RegExp: - case Function: - state = actual.toString().indexOf(arg) !== -1 - break - - case Object: - state = arg in actual - break - - case Array: - state = any(actual, function(value){ return equal(value, arg) }) - break - } - if (!state) return false - } - return true - }, - - throw_error : { match : function(actual, expected, message) { - try { actual() } - catch (e) { - this.e = e - var assert = function(arg) { - switch (arg.constructor) { - case RegExp : return arg.test(e.message || e.toString()) - case String : return arg == (e.message || e.toString()) - case Function : return e instanceof arg || e.name == arg.name - } - } - return message ? assert(expected) && assert(message) : - expected ? assert(expected) : - true - } - }, message : function(actual, expected, negate) { - // TODO: refactor when actual is not in expected [0] - var message_for = function(i) { - if (expected[i] == undefined) return 'exception' - switch (expected[i].constructor) { - case RegExp : return 'exception matching ' + puts(expected[i]) - case String : return 'exception of ' + puts(expected[i]) - case Function : return expected[i].name || 'Error' - } - } - exception = message_for(1) + (expected[2] ? ' and ' + message_for(2) : '') - return 'expected ' + exception + (negate ? ' not ' : '' ) + - ' to be thrown, but ' + (this.e ? 'got ' + puts(this.e) : 'nothing was') - }}, - - have : function(actual, length, property) { - return actual[property].length == length - }, - - have_at_least : function(actual, length, property) { - return actual[property].length >= length - }, - - have_at_most :function(actual, length, property) { - return actual[property].length <= length - }, - - have_within : function(actual, range, property) { - length = actual[property].length - return length >= range.shift() && length <= range.pop() - }, - - have_prop : function(actual, property, value) { - return actual[property] == null || - actual[property] instanceof Function ? false: - value == null ? true: - does(actual[property], 'eql', value) - }, - - have_property : function(actual, property, value) { - return actual[property] == null || - actual[property] instanceof Function ? false: - value == null ? true: - value === actual[property] - } - }) - -})() diff --git a/spec/lib/jspec.shell.js b/spec/lib/jspec.shell.js deleted file mode 100644 index cb19c69..0000000 --- a/spec/lib/jspec.shell.js +++ /dev/null @@ -1,39 +0,0 @@ - -// JSpec - Shell - Copyright TJ Holowaychuk (MIT Licensed) - -;(function(){ - - var _quit = quit - - Shell = { - - // --- Global - - main: this, - - // --- Commands - - commands: { - quit: ['Terminate the shell', function(){ _quit() }], - exit: ['Terminate the shell', function(){ _quit() }], - p: ['Inspect an object', function(o){ return o.toSource() }] - }, - - /** - * Start the interactive shell. - * - * @api public - */ - - start : function() { - for (var name in this.commands) - if (this.commands.hasOwnProperty(name)) - this.commands[name][1].length ? - this.main[name] = this.commands[name][1] : - this.main.__defineGetter__(name, this.commands[name][1]) - } - } - - Shell.start() - -})() \ No newline at end of file diff --git a/spec/lib/jspec.timers.js b/spec/lib/jspec.timers.js deleted file mode 100644 index c88d10b..0000000 --- a/spec/lib/jspec.timers.js +++ /dev/null @@ -1,90 +0,0 @@ - -// JSpec - Mock Timers - Copyright TJ Holowaychuk (MIT Licensed) - -;(function(){ - - /** - * Version. - */ - - mockTimersVersion = '1.0.2' - - /** - * Localized timer stack. - */ - - var timers = [] - - /** - * Set mock timeout with _callback_ and timeout of _ms_. - * - * @param {function} callback - * @param {int} ms - * @return {int} - * @api public - */ - - setTimeout = function(callback, ms) { - var id - return id = setInterval(function(){ - callback() - clearInterval(id) - }, ms) - } - - /** - * Set mock interval with _callback_ and interval of _ms_. - * - * @param {function} callback - * @param {int} ms - * @return {int} - * @api public - */ - - setInterval = function(callback, ms) { - callback.step = ms, callback.current = callback.last = 0 - return timers[timers.length] = callback, timers.length - } - - /** - * Destroy timer with _id_. - * - * @param {int} id - * @return {bool} - * @api public - */ - - clearInterval = clearTimeout = function(id) { - return delete timers[--id] - } - - /** - * Reset timers. - * - * @return {array} - * @api public - */ - - resetTimers = function() { - return timers = [] - } - - /** - * Increment each timers internal clock by _ms_. - * - * @param {int} ms - * @api public - */ - - tick = function(ms) { - for (var i = 0, len = timers.length; i < len; ++i) - if (timers[i] && (timers[i].current += ms)) - if (timers[i].current - timers[i].last >= timers[i].step) { - var times = Math.floor((timers[i].current - timers[i].last) / timers[i].step) - var remainder = (timers[i].current - timers[i].last) % timers[i].step - timers[i].last = timers[i].current - remainder - while (times-- && timers[i]) timers[i]() - } - } - -})() \ No newline at end of file diff --git a/spec/lib/jspec.xhr.js b/spec/lib/jspec.xhr.js deleted file mode 100644 index 906e4c5..0000000 --- a/spec/lib/jspec.xhr.js +++ /dev/null @@ -1,193 +0,0 @@ - -// JSpec - XHR - Copyright TJ Holowaychuk (MIT Licensed) - -(function(){ - - // --- Original XMLHttpRequest - - var OriginalXMLHttpRequest = 'XMLHttpRequest' in this ? - XMLHttpRequest : - function(){} - var OriginalActiveXObject = 'ActiveXObject' in this ? - ActiveXObject : - undefined - - // --- MockXMLHttpRequest - - var MockXMLHttpRequest = function() { - this.requestHeaders = {} - } - - MockXMLHttpRequest.prototype = { - status: 0, - async: true, - readyState: 0, - responseText: '', - abort: function(){}, - onreadystatechange: function(){}, - - /** - * Return response headers hash. - */ - - getAllResponseHeaders : function(){ - return this.responseHeaders - }, - - /** - * Return case-insensitive value for header _name_. - */ - - getResponseHeader : function(name) { - return this.responseHeaders[name.toLowerCase()] - }, - - /** - * Set case-insensitive _value_ for header _name_. - */ - - setRequestHeader : function(name, value) { - this.requestHeaders[name.toLowerCase()] = value - }, - - /** - * Open mock request. - */ - - open : function(method, url, async, user, password) { - this.user = user - this.password = password - this.url = url - this.readyState = 1 - this.method = method.toUpperCase() - if (async != undefined) this.async = async - if (this.async) this.onreadystatechange() - }, - - /** - * Send request _data_. - */ - - send : function(data) { - var self = this - this.data = data - this.readyState = 4 - if (this.method == 'HEAD') this.responseText = null - this.responseHeaders['content-length'] = (this.responseText || '').length - if(this.async) this.onreadystatechange() - lastRequest = function(){ - return self - } - } - } - - // --- Response status codes - - JSpec.statusCodes = { - 100: 'Continue', - 101: 'Switching Protocols', - 200: 'OK', - 201: 'Created', - 202: 'Accepted', - 203: 'Non-Authoritative Information', - 204: 'No Content', - 205: 'Reset Content', - 206: 'Partial Content', - 300: 'Multiple Choice', - 301: 'Moved Permanently', - 302: 'Found', - 303: 'See Other', - 304: 'Not Modified', - 305: 'Use Proxy', - 307: 'Temporary Redirect', - 400: 'Bad Request', - 401: 'Unauthorized', - 402: 'Payment Required', - 403: 'Forbidden', - 404: 'Not Found', - 405: 'Method Not Allowed', - 406: 'Not Acceptable', - 407: 'Proxy Authentication Required', - 408: 'Request Timeout', - 409: 'Conflict', - 410: 'Gone', - 411: 'Length Required', - 412: 'Precondition Failed', - 413: 'Request Entity Too Large', - 414: 'Request-URI Too Long', - 415: 'Unsupported Media Type', - 416: 'Requested Range Not Satisfiable', - 417: 'Expectation Failed', - 422: 'Unprocessable Entity', - 500: 'Internal Server Error', - 501: 'Not Implemented', - 502: 'Bad Gateway', - 503: 'Service Unavailable', - 504: 'Gateway Timeout', - 505: 'HTTP Version Not Supported' - } - - /** - * Mock XMLHttpRequest requests. - * - * mockRequest().and_return('some data', 'text/plain', 200, { 'X-SomeHeader' : 'somevalue' }) - * - * @return {hash} - * @api public - */ - - function mockRequest() { - return { and_return : function(body, type, status, headers) { - XMLHttpRequest = MockXMLHttpRequest - ActiveXObject = false - status = status || 200 - headers = headers || {} - headers['content-type'] = type - JSpec.extend(XMLHttpRequest.prototype, { - responseText: body, - responseHeaders: headers, - status: status, - statusText: JSpec.statusCodes[status] - }) - }} - } - - /** - * Unmock XMLHttpRequest requests. - * - * @api public - */ - - function unmockRequest() { - XMLHttpRequest = OriginalXMLHttpRequest - ActiveXObject = OriginalActiveXObject - } - - JSpec.include({ - name: 'Mock XHR', - - // --- Utilities - - utilities : { - mockRequest: mockRequest, - unmockRequest: unmockRequest - }, - - // --- Hooks - - afterSpec : function() { - unmockRequest() - }, - - // --- DSLs - - DSLs : { - snake : { - mock_request: mockRequest, - unmock_request: unmockRequest, - last_request: function(){ return lastRequest() } - } - } - - }) -})() \ No newline at end of file diff --git a/spec/spec.logging.js b/spec/spec.logging.js deleted file mode 100644 index 4e6f923..0000000 --- a/spec/spec.logging.js +++ /dev/null @@ -1,113 +0,0 @@ -describe 'log4js' - before - extend(context, { - log4js : require("log4js")() - }); - end - - before_each - log4js.clearAppenders(); - event = ''; - logger = log4js.getLogger('tests'); - logger.setLevel("TRACE"); - logger.addListener("log", function (logEvent) { event = logEvent; }); - end - - describe 'addAppender' - before_each - appenderEvent = undefined; - appender = function(logEvent) { appenderEvent = logEvent; }; - end - - describe 'without a category' - it 'should register the function as a listener for all loggers' - log4js.addAppender(appender); - logger.debug("This is a test"); - appenderEvent.should.be event - end - - it 'should also register as an appender for loggers if an appender for that category is defined' - var otherEvent; - log4js.addAppender(appender); - log4js.addAppender(function (evt) { otherEvent = evt; }, 'cheese'); - - var cheeseLogger = log4js.getLogger('cheese'); - cheeseLogger.addListener("log", function (logEvent) { event = logEvent; }); - - cheeseLogger.debug('This is a test'); - - appenderEvent.should.be event - otherEvent.should.be event - - otherEvent = undefined; - appenderEvent = undefined; - log4js.getLogger('pants').debug("this should not be propagated to otherEvent"); - otherEvent.should.be undefined - appenderEvent.should.not.be undefined - appenderEvent.message.should.be "this should not be propagated to otherEvent" - - cheeseLogger = null; - end - end - - describe 'with a category' - it 'should only register the function as a listener for that category' - log4js.addAppender(appender, 'tests'); - - logger.debug('this is a test'); - appenderEvent.should.be event - - appenderEvent = undefined; - log4js.getLogger('some other category').debug('Cheese'); - appenderEvent.should.be undefined - end - end - - describe 'with multiple categories' - it 'should register the function as a listener for all the categories' - log4js.addAppender(appender, 'tests', 'biscuits'); - - logger.debug('this is a test'); - appenderEvent.should.be event - appenderEvent = undefined; - - var otherLogger = log4js.getLogger('biscuits'); - otherLogger.debug("mmm... garibaldis"); - appenderEvent.should.not.be undefined - appenderEvent.message.should.be "mmm... garibaldis" - appenderEvent = undefined; - - otherLogger = null; - - log4js.getLogger("something else").debug("pants"); - appenderEvent.should.be undefined - end - - it 'should register the function when the list of categories is an array' - log4js.addAppender(appender, ['tests', 'pants']); - - logger.debug('this is a test'); - appenderEvent.should.be event - appenderEvent = undefined; - - var otherLogger = log4js.getLogger('pants'); - otherLogger.debug("big pants"); - appenderEvent.should.not.be undefined - appenderEvent.message.should.be "big pants" - appenderEvent = undefined; - - otherLogger = null; - - log4js.getLogger("something else").debug("pants"); - appenderEvent.should.be undefined - end - end - end - - - - - - -end - diff --git a/test/logging.js b/test/logging.js index 92d674e..3be6d0a 100644 --- a/test/logging.js +++ b/test/logging.js @@ -244,6 +244,91 @@ vows.describe('log4js').addBatch({ } }, + 'addAppender' : { + topic: function() { + var log4js = require('../lib/log4js')(); + log4js.clearAppenders(); + return log4js; + }, + 'without a category': { + 'should register the function as a listener for all loggers': function (log4js) { + var appenderEvent, appender = function(evt) { appenderEvent = evt; }, logger = log4js.getLogger("tests"); + log4js.addAppender(appender); + logger.debug("This is a test"); + assert.equal(appenderEvent.message, "This is a test"); + assert.equal(appenderEvent.categoryName, "tests"); + assert.equal(appenderEvent.level.toString(), "DEBUG"); + }, + 'should also register as an appender for loggers if an appender for that category is defined': function (log4js) { + var otherEvent, appenderEvent, cheeseLogger; + log4js.addAppender(function (evt) { appenderEvent = evt; }); + log4js.addAppender(function (evt) { otherEvent = evt; }, 'cheese'); + + cheeseLogger = log4js.getLogger('cheese'); + cheeseLogger.debug('This is a test'); + assert.deepEqual(appenderEvent, otherEvent); + assert.equal(otherEvent.message, 'This is a test'); + assert.equal(otherEvent.categoryName, 'cheese'); + + otherEvent = undefined; + appenderEvent = undefined; + log4js.getLogger('pants').debug("this should not be propagated to otherEvent"); + assert.isUndefined(otherEvent); + assert.equal(appenderEvent.message, "this should not be propagated to otherEvent"); + } + }, + + 'with a category': { + 'should only register the function as a listener for that category': function(log4js) { + var appenderEvent, appender = function(evt) { appenderEvent = evt; }, logger = log4js.getLogger("tests"); + log4js.addAppender(appender, 'tests'); + logger.debug('this is a category test'); + assert.equal(appenderEvent.message, 'this is a category test'); + + appenderEvent = undefined; + log4js.getLogger('some other category').debug('Cheese'); + assert.isUndefined(appenderEvent); + } + }, + + 'with multiple categories': { + 'should register the function as a listener for all the categories': function(log4js) { + var appenderEvent, appender = function(evt) { appenderEvent = evt; }, logger = log4js.getLogger('tests'); + log4js.addAppender(appender, 'tests', 'biscuits'); + + logger.debug('this is a test'); + assert.equal(appenderEvent.message, 'this is a test'); + appenderEvent = undefined; + + var otherLogger = log4js.getLogger('biscuits'); + otherLogger.debug("mmm... garibaldis"); + assert.equal(appenderEvent.message, "mmm... garibaldis"); + + appenderEvent = undefined; + + log4js.getLogger("something else").debug("pants"); + assert.isUndefined(appenderEvent); + }, + 'should register the function when the list of categories is an array': function(log4js) { + var appenderEvent, appender = function(evt) { appenderEvent = evt; }; + log4js.addAppender(appender, ['tests', 'pants']); + + log4js.getLogger('tests').debug('this is a test'); + assert.equal(appenderEvent.message, 'this is a test'); + + appenderEvent = undefined; + + log4js.getLogger('pants').debug("big pants"); + assert.equal(appenderEvent.message, "big pants"); + + appenderEvent = undefined; + + log4js.getLogger("something else").debug("pants"); + assert.isUndefined(appenderEvent); + } + } + }, + 'default setup': { topic: function() { var pathsChecked = [], diff --git a/tests.js b/tests.js deleted file mode 100644 index 3090813..0000000 --- a/tests.js +++ /dev/null @@ -1,43 +0,0 @@ -require.paths.unshift("./spec/lib", "./lib"); -require("jspec"); - -var sys = require("sys"), fs = require("fs"); - -quit = process.exit -print = sys.puts - -readFile = function(path) { - var result; - try { - result = fs.readFileSync(path, "utf8"); - } catch (e) { - throw e; - } - return result; -} - -var specsFound = false; - -if (process.ARGV[2]) { - specsFound = true; - JSpec.exec('spec/spec.' + process.ARGV[2] + '.js'); -} else { - var files = fs.readdirSync('spec/'); - files.filter( - function (file) { - return file.indexOf('spec.') === 0; - } - ).forEach( - function(file) { - specsFound = true; - JSpec.exec('spec/'+file); - } - ); -} -if (specsFound) { - JSpec.run({ reporter: JSpec.reporters.Terminal, failuresOnly: false }); - JSpec.report(); -} else { - print("No tests to run. This makes me sad."); -} -