diff --git a/.gitignore b/.gitignore index 3bbad47..cb14eaf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ nbproject manifest.mf build.xml +.project +.settings diff --git a/test/lib/jasmine-jstd-adapter/JasmineAdapter.js b/test/lib/jasmine-jstd-adapter/JasmineAdapter.js index 0fdc461..fb7306c 100644 --- a/test/lib/jasmine-jstd-adapter/JasmineAdapter.js +++ b/test/lib/jasmine-jstd-adapter/JasmineAdapter.js @@ -1,111 +1,176 @@ /** * @fileoverview Jasmine JsTestDriver Adapter. - * @author ibolmo@gmail.com (Olmo Maldonado) * @author misko@hevery.com (Misko Hevery) */ +(function(window) { + var rootDescribes = new Describes(window); + var describePath = []; + rootDescribes.collectMode(); + + var jasmineTest = TestCase('Jasmine Adapter Tests'); + + var jasminePlugin = { + name:'jasmine', + runTestConfiguration: function(testRunConfiguration, onTestDone, onTestRunConfigurationComplete){ + if (testRunConfiguration.testCaseInfo_.template_ !== jasmineTest) return; + + var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env(); + rootDescribes.playback(); + var specLog = jstestdriver.console.log_ = []; + var start; + jasmineEnv.specFilter = function(spec) { + return rootDescribes.isExclusive(spec); + }; + jasmineEnv.reporter = { + log: function(str){ + specLog.push(str); + }, -(function() { + reportRunnerStarting: function(runner) { }, - function bind(_this, _function){ - return function(){ - return _function.call(_this); - }; + reportSpecStarting: function(spec) { + specLog = jstestdriver.console.log_ = []; + start = new Date().getTime(); + }, + + reportSpecResults: function(spec) { + var suite = spec.suite; + var results = spec.results(); + if (results.skipped) return; + var end = new Date().getTime(); + var messages = []; + var resultItems = results.getItems(); + var state = 'passed'; + for ( var i = 0; i < resultItems.length; i++) { + if (!resultItems[i].passed()) { + state = resultItems[i].message.match(/AssertionError:/) ? 'error' : 'failed'; + messages.push(resultItems[i].toString()); + messages.push(formatStack(resultItems[i].trace.stack)); + } + } + onTestDone( + new jstestdriver.TestResult( + suite.getFullName(), + spec.description, + state, + messages.join('\n'), + specLog.join('\n'), + end - start)); + }, + + reportSuiteResults: function(suite) {}, + + reportRunnerResults: function(runner) { + onTestRunConfigurationComplete(); + } + }; + jasmineEnv.execute(); + return true; + }, + onTestsFinish: function(){ + jasmine.currentEnv_ = null; + rootDescribes.collectMode(); + } + }; + jstestdriver.pluginRegistrar.register(jasminePlugin); + + function formatStack(stack) { + var lines = (stack||'').split(/\r?\n/); + var frames = []; + for (i = 0; i < lines.length; i++) { + if (!lines[i].match(/\/jasmine[\.-]/)) { + frames.push(lines[i].replace(/https?:\/\/\w+(:\d+)?\/test\//, '').replace(/^\s*/, ' ')); + } + } + return frames.join('\n'); } - var currentFrame = frame(null, null); - - function frame(parent, name){ - var caseName = (parent && parent.caseName ? parent.caseName + " " : '') + (name ? name : ''); - var frame = { - name: name, - caseName: caseName, - parent: parent, - testCase: TestCase(caseName), - before: [], - after: [], - runBefore: function(){ - if (parent) parent.runBefore.apply(this); - for ( var i = 0; i < frame.before.length; i++) { - frame.before[i].apply(this); - } - }, - runAfter: function(){ - for ( var i = 0; i < frame.after.length; i++) { - frame.after[i].apply(this); - } - if (parent) parent.runAfter.apply(this); - } - }; - return frame; - }; - - jasmine.Env.prototype.describe = (function(describe){ - return function(description){ - currentFrame = frame(currentFrame, description); - var val = describe.apply(this, arguments); - currentFrame = currentFrame.parent; - return val; - }; - - })(jasmine.Env.prototype.describe); - - var id = 0; - - jasmine.Env.prototype.it = (function(it){ - return function(desc, itFn){ - var self = this; - var spec = it.apply(this, arguments); - var currentSpec = this.currentSpec; - if (!currentSpec.$id) { - currentSpec.$id = id++; - } - var frame = this.jstdFrame = currentFrame; - var name = 'test that it ' + desc; - if (this.jstdFrame.testCase.prototype[name]) - throw "Spec with name '" + desc + "' already exists."; - this.jstdFrame.testCase.prototype[name] = function(){ - jasmine.getEnv().currentSpec = currentSpec; - frame.runBefore.apply(currentSpec); - try { - itFn.apply(currentSpec); - } finally { - frame.runAfter.apply(currentSpec); + function noop(){} + function Describes(window){ + var describes = {}; + var beforeEachs = {}; + var afterEachs = {}; + var exclusive; + var collectMode = true; + intercept('describe', describes); + intercept('xdescribe', describes); + intercept('beforeEach', beforeEachs); + intercept('afterEach', afterEachs); + + function intercept(functionName, collection){ + window[functionName] = function(desc, fn){ + if (collectMode) { + collection[desc] = function(){ + jasmine.getEnv()[functionName](desc, fn); + }; + } else { + jasmine.getEnv()[functionName](desc, fn); } }; - return spec; + } + window.ddescribe = function(name, fn){ + exclusive = true; + console.log('ddescribe', name); + window.describe(name, function(){ + var oldIt = window.it; + window.it = window.iit; + try { + fn.call(this); + } finally { + window.it = oldIt; + }; + }); }; - - })(jasmine.Env.prototype.it); - - - jasmine.Env.prototype.beforeEach = (function(beforeEach){ - return function(beforeEachFunction) { - beforeEach.apply(this, arguments); - currentFrame.before.push(beforeEachFunction); + window.iit = function(name, fn){ + exclusive = fn.exclusive = true; + console.log(fn); + jasmine.getEnv().it(name, fn); }; - - })(jasmine.Env.prototype.beforeEach); - - - jasmine.Env.prototype.afterEach = (function(afterEach){ - return function(afterEachFunction) { - afterEach.apply(this, arguments); - currentFrame.after.push(afterEachFunction); + + + this.collectMode = function() { + collectMode = true; + exclusive = false; }; - - })(jasmine.Env.prototype.afterEach); - - - jasmine.NestedResults.prototype.addResult = (function(addResult){ - return function(result) { - addResult.call(this, result); - if (result.type != 'MessageResult' && !result.passed()) fail(result.message); + this.playback = function(){ + collectMode = false; + playback(beforeEachs); + playback(afterEachs); + playback(describes); + + function playback(set) { + for ( var name in set) { + set[name](); + } + } }; + + this.isExclusive = function(spec) { + if (exclusive) { + var blocks = spec.queue.blocks; + for ( var i = 0; i < blocks.length; i++) { + if (blocks[i].func.exclusive) { + return true; + } + } + return false; + } + return true; + }; + } + +})(window); - })(jasmine.NestedResults.prototype.addResult); +// Patch Jasmine for proper stack traces +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception' + }); + // PATCH + if (e) { + expectationResult.trace = e; + } + this.results_.addResult(expectationResult); +}; - // Reset environment with overriden methods. - jasmine.currentEnv_ = null; - jasmine.getEnv(); - -})();