jstd 1.3.1+ and jasmine-jstd-adapter upgrade
[angular-drzb] / test / lib / jasmine-jstd-adapter / JasmineAdapter.js
1 /**
2  * @fileoverview Jasmine JsTestDriver Adapter.
3  * @author misko@hevery.com (Misko Hevery)
4  */
5 (function(window) {
6   var rootDescribes = new Describes(window);
7   var describePath = [];
8   rootDescribes.collectMode();
9   
10   var jasmineTest = TestCase('Jasmine Adapter Tests', null, 'jasmine test case');
11   
12   var jasminePlugin = {
13       name:'jasmine',
14       runTestConfiguration: function(testRunConfiguration, onTestDone, onTestRunConfigurationComplete){
15         if (testRunConfiguration.testCaseInfo_.template_ !== jasmineTest) return;
16         
17         var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env();
18         rootDescribes.playback();
19         var specLog = jstestdriver.console.log_ = [];
20         var start;
21         jasmineEnv.specFilter = function(spec) {
22           return rootDescribes.isExclusive(spec);
23         };
24         jasmineEnv.reporter = {
25           log: function(str){
26             specLog.push(str);
27           },
28
29           reportRunnerStarting: function(runner) { },
30
31           reportSpecStarting: function(spec) {
32             specLog = jstestdriver.console.log_ = [];
33             start = new Date().getTime();
34           },
35
36           reportSpecResults: function(spec) {
37             var suite = spec.suite;
38             var results = spec.results();
39             if (results.skipped) return;
40             var end = new Date().getTime();
41             var messages = [];
42             var resultItems = results.getItems();
43             var state = 'passed';
44             for ( var i = 0; i < resultItems.length; i++) {
45               if (!resultItems[i].passed()) {
46                 state = resultItems[i].message.match(/AssertionError:/) ? 'error' : 'failed';
47                 messages.push({
48                         message: resultItems[i].toString(),
49                         name: resultItems[i].trace.name,
50                         stack: formatStack(resultItems[i].trace.stack)
51                 });
52               }
53             }
54             onTestDone(
55               new jstestdriver.TestResult(
56                 suite.getFullName(), 
57                 spec.description, 
58                 state, 
59                 jstestdriver.angular.toJson(messages),
60                 specLog.join('\n'),
61                 end - start));
62           },
63
64           reportSuiteResults: function(suite) {},
65           
66           reportRunnerResults: function(runner) {
67             onTestRunConfigurationComplete();
68           }
69         };
70         jasmineEnv.execute();
71         return true;
72       },
73       onTestsFinish: function(){
74         jasmine.currentEnv_ = null;
75         rootDescribes.collectMode();
76       }
77   };
78   jstestdriver.pluginRegistrar.register(jasminePlugin);
79
80   function formatStack(stack) {
81     var lines = (stack||'').split(/\r?\n/);
82     var frames = [];
83     for (i = 0; i < lines.length; i++) {
84       if (!lines[i].match(/\/jasmine[\.-]/)) {
85         frames.push(lines[i].replace(/https?:\/\/\w+(:\d+)?\/test\//, '').replace(/^\s*/, '      '));
86       }
87     }
88     return frames.join('\n');
89   }
90
91   function noop(){}
92   function Describes(window){
93     var describes = {};
94     var beforeEachs = {};
95     var afterEachs = {};
96     var exclusive;
97     var collectMode = true;
98     intercept('describe', describes);
99     intercept('xdescribe', describes);
100     intercept('beforeEach', beforeEachs);
101     intercept('afterEach', afterEachs);
102     
103     function intercept(functionName, collection){
104       window[functionName] = function(desc, fn){
105         if (collectMode) {
106           collection[desc] = function(){
107             jasmine.getEnv()[functionName](desc, fn);
108           };
109         } else {
110           jasmine.getEnv()[functionName](desc, fn);
111         }
112       };
113     }
114     window.ddescribe = function(name, fn){
115       exclusive = true;
116       console.log('ddescribe', name);
117       window.describe(name, function(){
118         var oldIt = window.it;
119         window.it = window.iit;
120         try {
121           fn.call(this);
122         } finally {
123           window.it = oldIt;
124         };
125       });
126     };
127     window.iit = function(name, fn){
128       exclusive = fn.exclusive = true;
129       console.log(fn);
130       jasmine.getEnv().it(name, fn);
131     };
132     
133     
134     this.collectMode = function() {
135       collectMode = true;
136       exclusive = false;
137     };
138     this.playback = function(){
139       collectMode = false;
140       playback(beforeEachs);
141       playback(afterEachs);
142       playback(describes);
143       
144       function playback(set) {
145         for ( var name in set) {
146           set[name]();
147         }
148       }
149     };
150     
151     this.isExclusive = function(spec) {
152       if (exclusive) {
153         var blocks = spec.queue.blocks;
154         for ( var i = 0; i < blocks.length; i++) {
155           if (blocks[i].func.exclusive) {
156             return true;
157           }
158         }
159         return false;
160       }
161       return true;
162     };
163   }
164   
165 })(window);
166
167 // Patch Jasmine for proper stack traces
168 jasmine.Spec.prototype.fail = function (e) {
169   var expectationResult = new jasmine.ExpectationResult({
170     passed: false,
171     message: e ? jasmine.util.formatException(e) : 'Exception'
172   });
173   // PATCH
174   if (e) {
175     expectationResult.trace = e;
176   }
177   this.results_.addResult(expectationResult);
178 };
179