3 var formatFailedStep = function(step) {
4 var stack = step.stack;
5 var message = step.message;
8 // remove the trailing dot
9 var firstLine = stack.substring(0, stack.indexOf('\n') - 1);
11 if (message && message.indexOf(firstLine) === -1) {
12 stack = message +'\n'+ stack;
15 // remove jasmine stack entries
16 return stack.replace(/\n.+jasmine\.js\?\w*\:.+(?=(\n|$))/g, '');
23 var indexOf = function(collection, item) {
24 if (collection.indexOf) {
25 return collection.indexOf(item);
28 for (var i = 0, l = collection.length; i < l; i++) {
29 if (collection[i] === item) {
38 var SuiteNode = function(name, parent) {
43 this.addChild = function(name) {
44 var suite = new SuiteNode(name, this);
45 this.children.push(suite);
51 var getAllSpecNames = function(topSuite) {
54 function processSuite(suite, pointer) {
58 for (var i = 0; i < suite.children.length; i++) {
59 child = suite.children[i];
62 childPointer = pointer[child.description] = {_: []};
63 processSuite(child, childPointer);
65 pointer._.push(child.description);
70 processSuite(topSuite, specNames);
77 * Very simple reporter for Jasmine.
79 var KarmaReporter = function(tc, jasmineEnv) {
81 var currentSuite = new SuiteNode();
84 * Jasmine 2.0 dispatches the following events:
94 this.jasmineStarted = function(data) {
95 // TODO(vojta): Do not send spec names when polling.
97 total: data.totalSpecsDefined,
98 specs: getAllSpecNames(jasmineEnv.topSuite())
103 this.jasmineDone = function() {
105 coverage: window.__coverage__
110 this.suiteStarted = function(result) {
111 currentSuite = currentSuite.addChild(result.description);
115 this.suiteDone = function(result) {
116 // In the case of xdescribe, only "suiteDone" is fired.
117 // We need to skip that.
118 if (result.description !== currentSuite.name) {
122 currentSuite = currentSuite.parent;
126 this.specStarted = function(specResult) {
127 specResult.startTime = new Date().getTime();
131 this.specDone = function(specResult) {
132 var skipped = specResult.status === 'disabled' || specResult.status === 'pending';
135 description : specResult.description,
139 success : specResult.failedExpectations.length === 0,
141 time : skipped ? 0 : new Date().getTime() - specResult.startTime
144 // generate ordered list of (nested) suite names
145 var suitePointer = currentSuite;
146 while (suitePointer.parent) {
147 result.suite.unshift(suitePointer.name);
148 suitePointer = suitePointer.parent;
151 if (!result.success) {
152 var steps = specResult.failedExpectations;
153 for (var i = 0, l = steps.length; i < l; i++) {
154 result.log.push(formatFailedStep(steps[i]));
159 delete specResult.startTime;
164 var createStartFn = function(tc, jasmineEnvPassedIn) {
165 return function(config) {
166 // we pass jasmineEnv during testing
167 // in production we ask for it lazily, so that adapter can be loaded even before jasmine
168 var jasmineEnv = jasmineEnvPassedIn || window.jasmine.getEnv();
170 jasmineEnv.addReporter(new KarmaReporter(tc, jasmineEnv));
171 jasmineEnv.executeFiltered();
176 window.__karma__.start = createStartFn(window.__karma__);