diff --git a/.gitignore b/.gitignore index 9f11b75..4c0b8ea 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea/ +.svn/ diff --git a/contrib/ruby/jasmine_runner.rb b/contrib/ruby/jasmine_runner.rb index dee3b71..44f3026 100644 --- a/contrib/ruby/jasmine_runner.rb +++ b/contrib/ruby/jasmine_runner.rb @@ -173,21 +173,18 @@ module Jasmine def eval_js(script) escaped_script = "'" + script.gsub(/(['\\])/) { '\\' + $1 } + "'" - begin - result = @driver.get_eval("window.eval(#{escaped_script})") - rescue Selenium::CommandError - result = @driver.get_eval("eval(#{escaped_script}, window)") - end + result = @driver.get_eval(" try { eval(#{escaped_script}, window); } catch(err) { window.eval(#{escaped_script}); }") JSON.parse("[#{result}]")[0] end end class Runner - def initialize(selenium_jar_path, spec_files, dir_mappings, jasmine_files = nil) + def initialize(selenium_jar_path, spec_files, dir_mappings, jasmine_files = nil, options={}) @selenium_jar_path = selenium_jar_path @spec_files = spec_files @dir_mappings = dir_mappings @jasmine_files = jasmine_files + @browser = options[:browser] || 'firefox' @selenium_pid = nil @jasmine_server_pid = nil @@ -195,7 +192,7 @@ module Jasmine def start start_servers - @client = Jasmine::SimpleClient.new("localhost", @selenium_server_port, "*firefox", "http://localhost:#{@jasmine_server_port}/") + @client = Jasmine::SimpleClient.new("localhost", @selenium_server_port, "*#{@browser}", "http://localhost:#{@jasmine_server_port}/") @client.connect end diff --git a/contrib/ruby/jasmine_spec_builder.rb b/contrib/ruby/jasmine_spec_builder.rb index ab3ee11..260c9e2 100644 --- a/contrib/ruby/jasmine_spec_builder.rb +++ b/contrib/ruby/jasmine_spec_builder.rb @@ -1,5 +1,5 @@ require File.expand_path(File.join(File.dirname(__FILE__), "jasmine_runner.rb")) - +require 'enumerator' module Jasmine class SpecBuilder @@ -8,6 +8,7 @@ module Jasmine def initialize(spec_files, runner) @spec_files = spec_files @runner = runner + @spec_ids = [] end def start @@ -15,7 +16,7 @@ module Jasmine @runner.start load_suite_info - @spec_results = {} + wait_for_suites_to_finish_running end def stop @@ -61,16 +62,23 @@ module Jasmine end def results_for(spec_id) - spec_id = spec_id.to_s - return @spec_results[spec_id] if @spec_results[spec_id] + @spec_results ||= load_results + @spec_results[spec_id.to_s] + end - @spec_results[spec_id] = eval_js("JSON.stringify(jsApiReporter.resultsForSpec(#{spec_id}))") - while @spec_results[spec_id].nil? do - sleep 0.1 - @spec_results[spec_id] = eval_js("JSON.stringify(jsApiReporter.resultsForSpec(#{spec_id}))") + def load_results + @spec_results = {} + @spec_ids.each_slice(50) do |slice| + @spec_results.merge!(eval_js("JSON.stringify(jsApiReporter.resultsForSpecs(#{JSON.generate(slice)}))")) end + @spec_results + end - @spec_results[spec_id] + def wait_for_suites_to_finish_running + puts "Waiting for suite to finish in browser ..." + while !eval_js('jsApiReporter.finished') do + sleep 0.1 + end end def declare_suites @@ -99,7 +107,7 @@ module Jasmine def declare_spec(parent, spec) me = self example_name = spec["name"] - + @spec_ids << spec["id"] backtrace = @example_locations[parent.description + " " + example_name] parent.it example_name, {}, backtrace do me.report_spec(spec["id"]) @@ -124,7 +132,7 @@ module Jasmine out << "\n" end - unless message["passed_"] + if !message["passed"] && message["trace"]["stack"] stack_trace = message["trace"]["stack"].gsub(/
/, "\n").gsub(/<\/?b>/, " ") STDERR << stack_trace.gsub(/\(.*\)@http:\/\/localhost:[0-9]+\/specs\//, "/spec/") STDERR << "\n" @@ -143,4 +151,3 @@ module Jasmine end end end - \ No newline at end of file diff --git a/doc/files.html b/doc/files.html index f9c2a66..43b9de3 100644 --- a/doc/files.html +++ b/doc/files.html @@ -258,7 +258,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:06 GMT-0700 (PDT)
\ No newline at end of file diff --git a/doc/index.html b/doc/index.html index 3953036..25ff209 100644 --- a/doc/index.html +++ b/doc/index.html @@ -300,7 +300,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:06 GMT-0700 (PDT)
\ No newline at end of file diff --git a/doc/symbols/_global_.html b/doc/symbols/_global_.html index ff8e406..a213d4e 100644 --- a/doc/symbols/_global_.html +++ b/doc/symbols/_global_.html @@ -908,7 +908,7 @@ A convenience method that allows existing specs to be disabled temporarily durin
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Block.html b/doc/symbols/jasmine.Block.html index f9ad8a1..c25e4ff 100644 --- a/doc/symbols/jasmine.Block.html +++ b/doc/symbols/jasmine.Block.html @@ -339,7 +339,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Env.html b/doc/symbols/jasmine.Env.html index ddabd8f..7fd634f 100644 --- a/doc/symbols/jasmine.Env.html +++ b/doc/symbols/jasmine.Env.html @@ -507,7 +507,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.JsApiReporter.html b/doc/symbols/jasmine.JsApiReporter.html index ead711b..17e0443 100644 --- a/doc/symbols/jasmine.JsApiReporter.html +++ b/doc/symbols/jasmine.JsApiReporter.html @@ -316,7 +316,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.MultiReporter.html b/doc/symbols/jasmine.MultiReporter.html index 1190994..29aa02c 100644 --- a/doc/symbols/jasmine.MultiReporter.html +++ b/doc/symbols/jasmine.MultiReporter.html @@ -316,7 +316,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.NestedResults.html b/doc/symbols/jasmine.NestedResults.html index ca7cc40..d3022fe 100644 --- a/doc/symbols/jasmine.NestedResults.html +++ b/doc/symbols/jasmine.NestedResults.html @@ -700,7 +700,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Reporter.html b/doc/symbols/jasmine.Reporter.html index cd7b660..1f51f1c 100644 --- a/doc/symbols/jasmine.Reporter.html +++ b/doc/symbols/jasmine.Reporter.html @@ -316,7 +316,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Runner.html b/doc/symbols/jasmine.Runner.html index bb0a5b8..de9cc93 100644 --- a/doc/symbols/jasmine.Runner.html +++ b/doc/symbols/jasmine.Runner.html @@ -418,7 +418,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Spec.html b/doc/symbols/jasmine.Spec.html index 2ad34e4..a8a6e03 100644 --- a/doc/symbols/jasmine.Spec.html +++ b/doc/symbols/jasmine.Spec.html @@ -396,7 +396,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Spy.html b/doc/symbols/jasmine.Spy.html index bb0fc83..ac4e9fe 100644 --- a/doc/symbols/jasmine.Spy.html +++ b/doc/symbols/jasmine.Spy.html @@ -845,7 +845,7 @@ expect(foo.bar.callCount).toEqual(0);
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:06 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.Suite.html b/doc/symbols/jasmine.Suite.html index c19a0ba..f57de14 100644 --- a/doc/symbols/jasmine.Suite.html +++ b/doc/symbols/jasmine.Suite.html @@ -436,7 +436,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:06 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.html b/doc/symbols/jasmine.html index 6355af2..42a13c0 100644 --- a/doc/symbols/jasmine.html +++ b/doc/symbols/jasmine.html @@ -678,7 +678,7 @@ Jasmine environment.
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:32 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:05 GMT-0700 (PDT)
diff --git a/doc/symbols/jasmine.util.html b/doc/symbols/jasmine.util.html index cdcc06c..780b4e8 100644 --- a/doc/symbols/jasmine.util.html +++ b/doc/symbols/jasmine.util.html @@ -316,7 +316,7 @@ ul.inheritsList
- Documentation generated by JsDoc Toolkit 2.1.0 on Mon Sep 28 2009 16:21:33 GMT-0700 (PDT) + Documentation generated by JsDoc Toolkit 2.1.0 on Tue Sep 29 2009 22:08:06 GMT-0700 (PDT)
diff --git a/doc/symbols/src/lib_TrivialReporter.js.html b/doc/symbols/src/lib_TrivialReporter.js.html index 32a15cb..6835f5a 100644 --- a/doc/symbols/src/lib_TrivialReporter.js.html +++ b/doc/symbols/src/lib_TrivialReporter.js.html @@ -19,7 +19,7 @@ 12 if (typeof child === 'string') { 13 el.appendChild(document.createTextNode(child)); 14 } else { - 15 el.appendChild(child); + 15 if (child) { el.appendChild(child); } 16 } 17 } 18 diff --git a/doc/symbols/src/lib_jasmine-0.9.0.js.html b/doc/symbols/src/lib_jasmine-0.9.0.js.html index c061f8b..4f59dad 100644 --- a/doc/symbols/src/lib_jasmine-0.9.0.js.html +++ b/doc/symbols/src/lib_jasmine-0.9.0.js.html @@ -524,7 +524,7 @@ 517 "major": 0, 518 "minor": 9, 519 "build": 0, -520 "revision": 1254179423 +520 "revision": 1254286811 521 }; 522 /** 523 * @namespace @@ -931,1198 +931,1230 @@ 924 jasmine.JsApiReporter.prototype.log = function(str) { 925 }; 926 -927 jasmine.Matchers = function(env, actual, results) { -928 this.env = env; -929 this.actual = actual; -930 this.passing_message = 'Passed.'; -931 this.results_ = results || new jasmine.NestedResults(); -932 }; -933 -934 jasmine.Matchers.pp = function(str) { -935 return jasmine.util.htmlEscape(jasmine.pp(str)); -936 }; -937 -938 /** @deprecated */ -939 jasmine.Matchers.prototype.getResults = function() { -940 return this.results_; -941 }; -942 -943 jasmine.Matchers.prototype.results = function() { -944 return this.results_; -945 }; -946 -947 jasmine.Matchers.prototype.report = function(result, failing_message, details) { -948 this.results_.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details)); -949 return result; -950 }; -951 -952 /** -953 * Matcher that compares the actual to the expected using ===. -954 * -955 * @param expected -956 */ -957 jasmine.Matchers.prototype.toBe = function(expected) { -958 return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected) -959 + '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual) -960 + '<br />'); -961 }; -962 -963 /** -964 * Matcher that compares the actual to the expected using !== -965 * @param expected -966 */ -967 jasmine.Matchers.prototype.toNotBe = function(expected) { -968 return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected) -969 + '<br /><br />to be a different object from actual, but they were the same.'); -970 }; -971 -972 /** -973 * Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. -974 * -975 * @param expected -976 */ -977 jasmine.Matchers.prototype.toEqual = function(expected) { -978 var mismatchKeys = []; -979 var mismatchValues = []; -980 -981 var formatMismatches = function(name, array) { -982 if (array.length == 0) return ''; -983 var errorOutput = '<br /><br />Different ' + name + ':<br />'; -984 for (var i = 0; i < array.length; i++) { -985 errorOutput += array[i] + '<br />'; -986 } -987 return errorOutput; -988 }; -989 -990 return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues), -991 'Expected<br /><br />' + jasmine.Matchers.pp(expected) -992 + '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual) -993 + '<br />' -994 + formatMismatches('Keys', mismatchKeys) -995 + formatMismatches('Values', mismatchValues), { -996 matcherName: 'toEqual', expected: expected, actual: this.actual -997 }); -998 }; -999 /** @deprecated */ -1000 jasmine.Matchers.prototype.should_equal = jasmine.Matchers.prototype.toEqual; -1001 -1002 /** -1003 * Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual -1004 * @param expected -1005 */ -1006 jasmine.Matchers.prototype.toNotEqual = function(expected) { -1007 return this.report(!this.env.equals_(this.actual, expected), -1008 'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.'); -1009 }; -1010 /** @deprecated */ -1011 jasmine.Matchers.prototype.should_not_equal = jasmine.Matchers.prototype.toNotEqual; +927 jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ +928 var results = {}; +929 for (var i = 0; i < specIds.length; i++) { +930 var specId = specIds[i]; +931 results[specId] = this.summarizeResult_(this.results_[specId]); +932 } +933 return results; +934 }; +935 +936 jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ +937 var summaryMessages = []; +938 for (var messageIndex in result.messages) { +939 var resultMessage = result.messages[messageIndex]; +940 summaryMessages.push({ +941 text: resultMessage.text, +942 passed: resultMessage.passed ? resultMessage.passed() : true, +943 type: resultMessage.type, +944 message: resultMessage.message, +945 trace: { +946 stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined +947 } +948 }); +949 }; +950 +951 var summaryResult = { +952 result : result.result, +953 messages : summaryMessages +954 }; +955 +956 return summaryResult; +957 }; +958 +959 jasmine.Matchers = function(env, actual, results) { +960 this.env = env; +961 this.actual = actual; +962 this.passing_message = 'Passed.'; +963 this.results_ = results || new jasmine.NestedResults(); +964 }; +965 +966 jasmine.Matchers.pp = function(str) { +967 return jasmine.util.htmlEscape(jasmine.pp(str)); +968 }; +969 +970 /** @deprecated */ +971 jasmine.Matchers.prototype.getResults = function() { +972 return this.results_; +973 }; +974 +975 jasmine.Matchers.prototype.results = function() { +976 return this.results_; +977 }; +978 +979 jasmine.Matchers.prototype.report = function(result, failing_message, details) { +980 this.results_.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details)); +981 return result; +982 }; +983 +984 /** +985 * Matcher that compares the actual to the expected using ===. +986 * +987 * @param expected +988 */ +989 jasmine.Matchers.prototype.toBe = function(expected) { +990 return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected) +991 + '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual) +992 + '<br />'); +993 }; +994 +995 /** +996 * Matcher that compares the actual to the expected using !== +997 * @param expected +998 */ +999 jasmine.Matchers.prototype.toNotBe = function(expected) { +1000 return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected) +1001 + '<br /><br />to be a different object from actual, but they were the same.'); +1002 }; +1003 +1004 /** +1005 * Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. +1006 * +1007 * @param expected +1008 */ +1009 jasmine.Matchers.prototype.toEqual = function(expected) { +1010 var mismatchKeys = []; +1011 var mismatchValues = []; 1012 -1013 /** -1014 * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes -1015 * a pattern or a String. -1016 * -1017 * @param reg_exp -1018 */ -1019 jasmine.Matchers.prototype.toMatch = function(reg_exp) { -1020 return this.report((new RegExp(reg_exp).test(this.actual)), -1021 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.'); -1022 }; -1023 /** @deprecated */ -1024 jasmine.Matchers.prototype.should_match = jasmine.Matchers.prototype.toMatch; -1025 -1026 /** -1027 * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch -1028 * @param reg_exp -1029 */ -1030 jasmine.Matchers.prototype.toNotMatch = function(reg_exp) { -1031 return this.report((!new RegExp(reg_exp).test(this.actual)), -1032 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.'); -1033 }; -1034 /** @deprecated */ -1035 jasmine.Matchers.prototype.should_not_match = jasmine.Matchers.prototype.toNotMatch; -1036 -1037 /** -1038 * Matcher that compares the acutal to undefined. -1039 */ -1040 jasmine.Matchers.prototype.toBeDefined = function() { -1041 return this.report((this.actual !== undefined), -1042 'Expected a value to be defined but it was undefined.'); -1043 }; -1044 /** @deprecated */ -1045 jasmine.Matchers.prototype.should_be_defined = jasmine.Matchers.prototype.toBeDefined; -1046 -1047 /** -1048 * Matcher that compares the actual to null. -1049 * +1013 var formatMismatches = function(name, array) { +1014 if (array.length == 0) return ''; +1015 var errorOutput = '<br /><br />Different ' + name + ':<br />'; +1016 for (var i = 0; i < array.length; i++) { +1017 errorOutput += array[i] + '<br />'; +1018 } +1019 return errorOutput; +1020 }; +1021 +1022 return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues), +1023 'Expected<br /><br />' + jasmine.Matchers.pp(expected) +1024 + '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual) +1025 + '<br />' +1026 + formatMismatches('Keys', mismatchKeys) +1027 + formatMismatches('Values', mismatchValues), { +1028 matcherName: 'toEqual', expected: expected, actual: this.actual +1029 }); +1030 }; +1031 /** @deprecated */ +1032 jasmine.Matchers.prototype.should_equal = jasmine.Matchers.prototype.toEqual; +1033 +1034 /** +1035 * Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual +1036 * @param expected +1037 */ +1038 jasmine.Matchers.prototype.toNotEqual = function(expected) { +1039 return this.report(!this.env.equals_(this.actual, expected), +1040 'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.'); +1041 }; +1042 /** @deprecated */ +1043 jasmine.Matchers.prototype.should_not_equal = jasmine.Matchers.prototype.toNotEqual; +1044 +1045 /** +1046 * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes +1047 * a pattern or a String. +1048 * +1049 * @param reg_exp 1050 */ -1051 jasmine.Matchers.prototype.toBeNull = function() { -1052 return this.report((this.actual === null), -1053 'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.'); +1051 jasmine.Matchers.prototype.toMatch = function(reg_exp) { +1052 return this.report((new RegExp(reg_exp).test(this.actual)), +1053 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.'); 1054 }; 1055 /** @deprecated */ -1056 jasmine.Matchers.prototype.should_be_null = jasmine.Matchers.prototype.toBeNull; +1056 jasmine.Matchers.prototype.should_match = jasmine.Matchers.prototype.toMatch; 1057 1058 /** -1059 * Matcher that boolean not-nots the actual. -1060 */ -1061 jasmine.Matchers.prototype.toBeTruthy = function() { -1062 return this.report(!!this.actual, -1063 'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.'); -1064 }; -1065 /** @deprecated */ -1066 jasmine.Matchers.prototype.should_be_truthy = jasmine.Matchers.prototype.toBeTruthy; -1067 -1068 /** -1069 * Matcher that boolean nots the actual. -1070 */ -1071 jasmine.Matchers.prototype.toBeFalsy = function() { -1072 return this.report(!this.actual, -1073 'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.'); -1074 }; -1075 /** @deprecated */ -1076 jasmine.Matchers.prototype.should_be_falsy = jasmine.Matchers.prototype.toBeFalsy; -1077 -1078 /** -1079 * Matcher that checks to see if the acutal, a Jasmine spy, was called. -1080 */ -1081 jasmine.Matchers.prototype.wasCalled = function() { -1082 if (!this.actual || !this.actual.isSpy) { -1083 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); -1084 } -1085 if (arguments.length > 0) { -1086 return this.report(false, 'wasCalled matcher does not take arguments'); -1087 } -1088 return this.report((this.actual.wasCalled), -1089 'Expected spy "' + this.actual.identity + '" to have been called, but it was not.'); -1090 }; -1091 /** @deprecated */ -1092 jasmine.Matchers.prototype.was_called = jasmine.Matchers.prototype.wasCalled; -1093 -1094 /** -1095 * Matcher that checks to see if the acutal, a Jasmine spy, was not called. -1096 */ -1097 jasmine.Matchers.prototype.wasNotCalled = function() { -1098 if (!this.actual || !this.actual.isSpy) { -1099 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); -1100 } -1101 return this.report((!this.actual.wasCalled), -1102 'Expected spy "' + this.actual.identity + '" to not have been called, but it was.'); -1103 }; -1104 /** @deprecated */ -1105 jasmine.Matchers.prototype.was_not_called = jasmine.Matchers.prototype.wasNotCalled; -1106 -1107 /** -1108 * Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters. -1109 * -1110 * @example -1111 * +1059 * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch +1060 * @param reg_exp +1061 */ +1062 jasmine.Matchers.prototype.toNotMatch = function(reg_exp) { +1063 return this.report((!new RegExp(reg_exp).test(this.actual)), +1064 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.'); +1065 }; +1066 /** @deprecated */ +1067 jasmine.Matchers.prototype.should_not_match = jasmine.Matchers.prototype.toNotMatch; +1068 +1069 /** +1070 * Matcher that compares the acutal to undefined. +1071 */ +1072 jasmine.Matchers.prototype.toBeDefined = function() { +1073 return this.report((this.actual !== undefined), +1074 'Expected a value to be defined but it was undefined.'); +1075 }; +1076 /** @deprecated */ +1077 jasmine.Matchers.prototype.should_be_defined = jasmine.Matchers.prototype.toBeDefined; +1078 +1079 /** +1080 * Matcher that compares the actual to null. +1081 * +1082 */ +1083 jasmine.Matchers.prototype.toBeNull = function() { +1084 return this.report((this.actual === null), +1085 'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.'); +1086 }; +1087 /** @deprecated */ +1088 jasmine.Matchers.prototype.should_be_null = jasmine.Matchers.prototype.toBeNull; +1089 +1090 /** +1091 * Matcher that boolean not-nots the actual. +1092 */ +1093 jasmine.Matchers.prototype.toBeTruthy = function() { +1094 return this.report(!!this.actual, +1095 'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.'); +1096 }; +1097 /** @deprecated */ +1098 jasmine.Matchers.prototype.should_be_truthy = jasmine.Matchers.prototype.toBeTruthy; +1099 +1100 /** +1101 * Matcher that boolean nots the actual. +1102 */ +1103 jasmine.Matchers.prototype.toBeFalsy = function() { +1104 return this.report(!this.actual, +1105 'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.'); +1106 }; +1107 /** @deprecated */ +1108 jasmine.Matchers.prototype.should_be_falsy = jasmine.Matchers.prototype.toBeFalsy; +1109 +1110 /** +1111 * Matcher that checks to see if the acutal, a Jasmine spy, was called. 1112 */ -1113 jasmine.Matchers.prototype.wasCalledWith = function() { +1113 jasmine.Matchers.prototype.wasCalled = function() { 1114 if (!this.actual || !this.actual.isSpy) { -1115 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', { -1116 matcherName: 'wasCalledWith' -1117 }); -1118 } -1119 -1120 var args = jasmine.util.argsToArray(arguments); -1121 -1122 return this.report(this.env.contains_(this.actual.argsForCall, args), -1123 'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', { -1124 matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall -1125 }); -1126 }; -1127 -1128 /** -1129 * Matcher that checks that the expected item is an element in the actual Array. -1130 * -1131 * @param {Object} item -1132 */ -1133 jasmine.Matchers.prototype.toContain = function(item) { -1134 return this.report(this.env.contains_(this.actual, item), -1135 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', { -1136 matcherName: 'toContain', expected: item, actual: this.actual -1137 }); -1138 }; -1139 -1140 /** -1141 * Matcher that checks that the expected item is NOT an element in the actual Array. -1142 * -1143 * @param {Object} item +1115 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); +1116 } +1117 if (arguments.length > 0) { +1118 return this.report(false, 'wasCalled matcher does not take arguments'); +1119 } +1120 return this.report((this.actual.wasCalled), +1121 'Expected spy "' + this.actual.identity + '" to have been called, but it was not.'); +1122 }; +1123 /** @deprecated */ +1124 jasmine.Matchers.prototype.was_called = jasmine.Matchers.prototype.wasCalled; +1125 +1126 /** +1127 * Matcher that checks to see if the acutal, a Jasmine spy, was not called. +1128 */ +1129 jasmine.Matchers.prototype.wasNotCalled = function() { +1130 if (!this.actual || !this.actual.isSpy) { +1131 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.'); +1132 } +1133 return this.report((!this.actual.wasCalled), +1134 'Expected spy "' + this.actual.identity + '" to not have been called, but it was.'); +1135 }; +1136 /** @deprecated */ +1137 jasmine.Matchers.prototype.was_not_called = jasmine.Matchers.prototype.wasNotCalled; +1138 +1139 /** +1140 * Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters. +1141 * +1142 * @example +1143 * 1144 */ -1145 jasmine.Matchers.prototype.toNotContain = function(item) { -1146 return this.report(!this.env.contains_(this.actual, item), -1147 'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.'); -1148 }; -1149 -1150 jasmine.Matchers.prototype.toBeLessThan = function(expected) { -1151 return this.report(this.actual < expected, -1152 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.'); -1153 }; -1154 -1155 jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { -1156 return this.report(this.actual > expected, -1157 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.'); +1145 jasmine.Matchers.prototype.wasCalledWith = function() { +1146 if (!this.actual || !this.actual.isSpy) { +1147 return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', { +1148 matcherName: 'wasCalledWith' +1149 }); +1150 } +1151 +1152 var args = jasmine.util.argsToArray(arguments); +1153 +1154 return this.report(this.env.contains_(this.actual.argsForCall, args), +1155 'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', { +1156 matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall +1157 }); 1158 }; 1159 1160 /** -1161 * Matcher that checks that the expected exception was thrown by the actual. +1161 * Matcher that checks that the expected item is an element in the actual Array. 1162 * -1163 * @param {String} expectedException +1163 * @param {Object} item 1164 */ -1165 jasmine.Matchers.prototype.toThrow = function(expectedException) { -1166 var exception = null; -1167 try { -1168 this.actual(); -1169 } catch (e) { -1170 exception = e; -1171 } -1172 if (expectedException !== undefined) { -1173 if (exception == null) { -1174 return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not."); -1175 } -1176 return this.report( -1177 this.env.equals_( -1178 exception.message || exception, -1179 expectedException.message || expectedException), -1180 "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + "."); -1181 } else { -1182 return this.report(exception != null, "Expected function to throw an exception, but it did not."); -1183 } -1184 }; -1185 -1186 jasmine.Matchers.Any = function(expectedClass) { -1187 this.expectedClass = expectedClass; -1188 }; -1189 -1190 jasmine.Matchers.Any.prototype.matches = function(other) { -1191 if (this.expectedClass == String) { -1192 return typeof other == 'string' || other instanceof String; -1193 } -1194 -1195 if (this.expectedClass == Number) { -1196 return typeof other == 'number' || other instanceof Number; -1197 } -1198 -1199 if (this.expectedClass == Function) { -1200 return typeof other == 'function' || other instanceof Function; -1201 } -1202 -1203 if (this.expectedClass == Object) { -1204 return typeof other == 'object'; -1205 } -1206 -1207 return other instanceof this.expectedClass; -1208 }; -1209 -1210 jasmine.Matchers.Any.prototype.toString = function() { -1211 return '<jasmine.any(' + this.expectedClass + ')>'; -1212 }; -1213 -1214 /** -1215 * @constructor -1216 */ -1217 jasmine.MultiReporter = function() { -1218 this.subReporters_ = []; -1219 }; -1220 jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); +1165 jasmine.Matchers.prototype.toContain = function(item) { +1166 return this.report(this.env.contains_(this.actual, item), +1167 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', { +1168 matcherName: 'toContain', expected: item, actual: this.actual +1169 }); +1170 }; +1171 +1172 /** +1173 * Matcher that checks that the expected item is NOT an element in the actual Array. +1174 * +1175 * @param {Object} item +1176 */ +1177 jasmine.Matchers.prototype.toNotContain = function(item) { +1178 return this.report(!this.env.contains_(this.actual, item), +1179 'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.'); +1180 }; +1181 +1182 jasmine.Matchers.prototype.toBeLessThan = function(expected) { +1183 return this.report(this.actual < expected, +1184 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.'); +1185 }; +1186 +1187 jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { +1188 return this.report(this.actual > expected, +1189 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.'); +1190 }; +1191 +1192 /** +1193 * Matcher that checks that the expected exception was thrown by the actual. +1194 * +1195 * @param {String} expectedException +1196 */ +1197 jasmine.Matchers.prototype.toThrow = function(expectedException) { +1198 var exception = null; +1199 try { +1200 this.actual(); +1201 } catch (e) { +1202 exception = e; +1203 } +1204 if (expectedException !== undefined) { +1205 if (exception == null) { +1206 return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not."); +1207 } +1208 return this.report( +1209 this.env.equals_( +1210 exception.message || exception, +1211 expectedException.message || expectedException), +1212 "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + "."); +1213 } else { +1214 return this.report(exception != null, "Expected function to throw an exception, but it did not."); +1215 } +1216 }; +1217 +1218 jasmine.Matchers.Any = function(expectedClass) { +1219 this.expectedClass = expectedClass; +1220 }; 1221 -1222 jasmine.MultiReporter.prototype.addReporter = function(reporter) { -1223 this.subReporters_.push(reporter); -1224 }; -1225 -1226 (function() { -1227 var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"]; -1228 for (var i = 0; i < functionNames.length; i++) { -1229 var functionName = functionNames[i]; -1230 jasmine.MultiReporter.prototype[functionName] = (function(functionName) { -1231 return function() { -1232 for (var j = 0; j < this.subReporters_.length; j++) { -1233 var subReporter = this.subReporters_[j]; -1234 if (subReporter[functionName]) { -1235 subReporter[functionName].apply(subReporter, arguments); -1236 } -1237 } -1238 }; -1239 })(functionName); -1240 } -1241 })(); -1242 /** -1243 * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults -1244 * -1245 * @constructor -1246 */ -1247 jasmine.NestedResults = function() { -1248 /** -1249 * The total count of results -1250 */ -1251 this.totalCount = 0; -1252 /** -1253 * Number of passed results -1254 */ -1255 this.passedCount = 0; -1256 /** -1257 * Number of failed results -1258 */ -1259 this.failedCount = 0; -1260 /** -1261 * Was this suite/spec skipped? -1262 */ -1263 this.skipped = false; -1264 /** -1265 * @ignore -1266 */ -1267 this.items_ = []; -1268 }; -1269 -1270 /** -1271 * Roll up the result counts. -1272 * -1273 * @param result -1274 */ -1275 jasmine.NestedResults.prototype.rollupCounts = function(result) { -1276 this.totalCount += result.totalCount; -1277 this.passedCount += result.passedCount; -1278 this.failedCount += result.failedCount; -1279 }; -1280 -1281 /** -1282 * Tracks a result's message. -1283 * @param message -1284 */ -1285 jasmine.NestedResults.prototype.log = function(message) { -1286 this.items_.push(new jasmine.MessageResult(message)); -1287 }; -1288 -1289 /** -1290 * Getter for the results: message & results. -1291 */ -1292 jasmine.NestedResults.prototype.getItems = function() { -1293 return this.items_; -1294 }; -1295 -1296 /** -1297 * Adds a result, tracking counts (total, passed, & failed) -1298 * @param {jasmine.ExpectationResult|jasmine.NestedResults} result -1299 */ -1300 jasmine.NestedResults.prototype.addResult = function(result) { -1301 if (result.type != 'MessageResult') { -1302 if (result.items_) { -1303 this.rollupCounts(result); -1304 } else { -1305 this.totalCount++; -1306 if (result.passed()) { -1307 this.passedCount++; -1308 } else { -1309 this.failedCount++; -1310 } -1311 } -1312 } -1313 this.items_.push(result); -1314 }; -1315 -1316 /** -1317 * @returns {Boolean} True if <b>everything</b> below passed -1318 */ -1319 jasmine.NestedResults.prototype.passed = function() { -1320 return this.passedCount === this.totalCount; -1321 }; -1322 /** -1323 * Base class for pretty printing for expectation results. -1324 */ -1325 jasmine.PrettyPrinter = function() { -1326 this.ppNestLevel_ = 0; -1327 }; -1328 -1329 /** -1330 * Formats a value in a nice, human-readable string. -1331 * -1332 * @param value -1333 * @returns {String} -1334 */ -1335 jasmine.PrettyPrinter.prototype.format = function(value) { -1336 if (this.ppNestLevel_ > 40) { -1337 // return '(jasmine.pp nested too deeply!)'; -1338 throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); -1339 } -1340 -1341 this.ppNestLevel_++; -1342 try { -1343 if (value === undefined) { -1344 this.emitScalar('undefined'); -1345 } else if (value === null) { -1346 this.emitScalar('null'); -1347 } else if (value.navigator && value.frames && value.setTimeout) { -1348 this.emitScalar('<window>'); -1349 } else if (value instanceof jasmine.Matchers.Any) { -1350 this.emitScalar(value.toString()); -1351 } else if (typeof value === 'string') { -1352 this.emitString(value); -1353 } else if (typeof value === 'function') { -1354 this.emitScalar('Function'); -1355 } else if (typeof value.nodeType === 'number') { -1356 this.emitScalar('HTMLNode'); -1357 } else if (value instanceof Date) { -1358 this.emitScalar('Date(' + value + ')'); -1359 } else if (value.__Jasmine_been_here_before__) { -1360 this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>'); -1361 } else if (jasmine.isArray_(value) || typeof value == 'object') { -1362 value.__Jasmine_been_here_before__ = true; -1363 if (jasmine.isArray_(value)) { -1364 this.emitArray(value); -1365 } else { -1366 this.emitObject(value); -1367 } -1368 delete value.__Jasmine_been_here_before__; -1369 } else { -1370 this.emitScalar(value.toString()); -1371 } -1372 } finally { -1373 this.ppNestLevel_--; -1374 } -1375 }; -1376 -1377 jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { -1378 for (var property in obj) { -1379 if (property == '__Jasmine_been_here_before__') continue; -1380 fn(property, obj.__lookupGetter__(property) != null); -1381 } -1382 }; -1383 -1384 jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; -1385 jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; -1386 jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; -1387 jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; -1388 -1389 jasmine.StringPrettyPrinter = function() { -1390 jasmine.PrettyPrinter.call(this); -1391 -1392 this.string = ''; -1393 }; -1394 jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); -1395 -1396 jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { -1397 this.append(value); -1398 }; -1399 -1400 jasmine.StringPrettyPrinter.prototype.emitString = function(value) { -1401 this.append("'" + value + "'"); -1402 }; -1403 -1404 jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { -1405 this.append('[ '); -1406 for (var i = 0; i < array.length; i++) { -1407 if (i > 0) { -1408 this.append(', '); -1409 } -1410 this.format(array[i]); -1411 } -1412 this.append(' ]'); -1413 }; -1414 -1415 jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { -1416 var self = this; -1417 this.append('{ '); -1418 var first = true; -1419 -1420 this.iterateObject(obj, function(property, isGetter) { -1421 if (first) { -1422 first = false; -1423 } else { -1424 self.append(', '); -1425 } -1426 -1427 self.append(property); -1428 self.append(' : '); -1429 if (isGetter) { -1430 self.append('<getter>'); -1431 } else { -1432 self.format(obj[property]); -1433 } -1434 }); +1222 jasmine.Matchers.Any.prototype.matches = function(other) { +1223 if (this.expectedClass == String) { +1224 return typeof other == 'string' || other instanceof String; +1225 } +1226 +1227 if (this.expectedClass == Number) { +1228 return typeof other == 'number' || other instanceof Number; +1229 } +1230 +1231 if (this.expectedClass == Function) { +1232 return typeof other == 'function' || other instanceof Function; +1233 } +1234 +1235 if (this.expectedClass == Object) { +1236 return typeof other == 'object'; +1237 } +1238 +1239 return other instanceof this.expectedClass; +1240 }; +1241 +1242 jasmine.Matchers.Any.prototype.toString = function() { +1243 return '<jasmine.any(' + this.expectedClass + ')>'; +1244 }; +1245 +1246 /** +1247 * @constructor +1248 */ +1249 jasmine.MultiReporter = function() { +1250 this.subReporters_ = []; +1251 }; +1252 jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); +1253 +1254 jasmine.MultiReporter.prototype.addReporter = function(reporter) { +1255 this.subReporters_.push(reporter); +1256 }; +1257 +1258 (function() { +1259 var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"]; +1260 for (var i = 0; i < functionNames.length; i++) { +1261 var functionName = functionNames[i]; +1262 jasmine.MultiReporter.prototype[functionName] = (function(functionName) { +1263 return function() { +1264 for (var j = 0; j < this.subReporters_.length; j++) { +1265 var subReporter = this.subReporters_[j]; +1266 if (subReporter[functionName]) { +1267 subReporter[functionName].apply(subReporter, arguments); +1268 } +1269 } +1270 }; +1271 })(functionName); +1272 } +1273 })(); +1274 /** +1275 * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults +1276 * +1277 * @constructor +1278 */ +1279 jasmine.NestedResults = function() { +1280 /** +1281 * The total count of results +1282 */ +1283 this.totalCount = 0; +1284 /** +1285 * Number of passed results +1286 */ +1287 this.passedCount = 0; +1288 /** +1289 * Number of failed results +1290 */ +1291 this.failedCount = 0; +1292 /** +1293 * Was this suite/spec skipped? +1294 */ +1295 this.skipped = false; +1296 /** +1297 * @ignore +1298 */ +1299 this.items_ = []; +1300 }; +1301 +1302 /** +1303 * Roll up the result counts. +1304 * +1305 * @param result +1306 */ +1307 jasmine.NestedResults.prototype.rollupCounts = function(result) { +1308 this.totalCount += result.totalCount; +1309 this.passedCount += result.passedCount; +1310 this.failedCount += result.failedCount; +1311 }; +1312 +1313 /** +1314 * Tracks a result's message. +1315 * @param message +1316 */ +1317 jasmine.NestedResults.prototype.log = function(message) { +1318 this.items_.push(new jasmine.MessageResult(message)); +1319 }; +1320 +1321 /** +1322 * Getter for the results: message & results. +1323 */ +1324 jasmine.NestedResults.prototype.getItems = function() { +1325 return this.items_; +1326 }; +1327 +1328 /** +1329 * Adds a result, tracking counts (total, passed, & failed) +1330 * @param {jasmine.ExpectationResult|jasmine.NestedResults} result +1331 */ +1332 jasmine.NestedResults.prototype.addResult = function(result) { +1333 if (result.type != 'MessageResult') { +1334 if (result.items_) { +1335 this.rollupCounts(result); +1336 } else { +1337 this.totalCount++; +1338 if (result.passed()) { +1339 this.passedCount++; +1340 } else { +1341 this.failedCount++; +1342 } +1343 } +1344 } +1345 this.items_.push(result); +1346 }; +1347 +1348 /** +1349 * @returns {Boolean} True if <b>everything</b> below passed +1350 */ +1351 jasmine.NestedResults.prototype.passed = function() { +1352 return this.passedCount === this.totalCount; +1353 }; +1354 /** +1355 * Base class for pretty printing for expectation results. +1356 */ +1357 jasmine.PrettyPrinter = function() { +1358 this.ppNestLevel_ = 0; +1359 }; +1360 +1361 /** +1362 * Formats a value in a nice, human-readable string. +1363 * +1364 * @param value +1365 * @returns {String} +1366 */ +1367 jasmine.PrettyPrinter.prototype.format = function(value) { +1368 if (this.ppNestLevel_ > 40) { +1369 // return '(jasmine.pp nested too deeply!)'; +1370 throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); +1371 } +1372 +1373 this.ppNestLevel_++; +1374 try { +1375 if (value === undefined) { +1376 this.emitScalar('undefined'); +1377 } else if (value === null) { +1378 this.emitScalar('null'); +1379 } else if (value.navigator && value.frames && value.setTimeout) { +1380 this.emitScalar('<window>'); +1381 } else if (value instanceof jasmine.Matchers.Any) { +1382 this.emitScalar(value.toString()); +1383 } else if (typeof value === 'string') { +1384 this.emitString(value); +1385 } else if (typeof value === 'function') { +1386 this.emitScalar('Function'); +1387 } else if (typeof value.nodeType === 'number') { +1388 this.emitScalar('HTMLNode'); +1389 } else if (value instanceof Date) { +1390 this.emitScalar('Date(' + value + ')'); +1391 } else if (value.__Jasmine_been_here_before__) { +1392 this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>'); +1393 } else if (jasmine.isArray_(value) || typeof value == 'object') { +1394 value.__Jasmine_been_here_before__ = true; +1395 if (jasmine.isArray_(value)) { +1396 this.emitArray(value); +1397 } else { +1398 this.emitObject(value); +1399 } +1400 delete value.__Jasmine_been_here_before__; +1401 } else { +1402 this.emitScalar(value.toString()); +1403 } +1404 } finally { +1405 this.ppNestLevel_--; +1406 } +1407 }; +1408 +1409 jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { +1410 for (var property in obj) { +1411 if (property == '__Jasmine_been_here_before__') continue; +1412 fn(property, obj.__lookupGetter__(property) != null); +1413 } +1414 }; +1415 +1416 jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +1417 jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +1418 jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +1419 jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; +1420 +1421 jasmine.StringPrettyPrinter = function() { +1422 jasmine.PrettyPrinter.call(this); +1423 +1424 this.string = ''; +1425 }; +1426 jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); +1427 +1428 jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { +1429 this.append(value); +1430 }; +1431 +1432 jasmine.StringPrettyPrinter.prototype.emitString = function(value) { +1433 this.append("'" + value + "'"); +1434 }; 1435 -1436 this.append(' }'); -1437 }; -1438 -1439 jasmine.StringPrettyPrinter.prototype.append = function(value) { -1440 this.string += value; -1441 }; -1442 jasmine.Queue = function(env) { -1443 this.env = env; -1444 this.blocks = []; -1445 this.running = false; -1446 this.index = 0; -1447 this.offset = 0; -1448 }; -1449 -1450 jasmine.Queue.prototype.addBefore = function (block) { -1451 this.blocks.unshift(block); -1452 }; -1453 -1454 jasmine.Queue.prototype.add = function(block) { -1455 this.blocks.push(block); -1456 }; -1457 -1458 jasmine.Queue.prototype.insertNext = function (block) { -1459 this.blocks.splice((this.index + this.offset + 1), 0, block); -1460 this.offset++; -1461 }; -1462 -1463 jasmine.Queue.prototype.start = function(onComplete) { -1464 var self = this; -1465 self.running = true; -1466 self.onComplete = onComplete; -1467 if (self.blocks[0]) { -1468 self.blocks[0].execute(function () { -1469 self._next(); -1470 }); -1471 } else { -1472 self.finish(); -1473 } -1474 }; -1475 -1476 jasmine.Queue.prototype.isRunning = function () { -1477 return this.running; -1478 }; -1479 -1480 jasmine.Queue.prototype._next = function () { -1481 var self = this; -1482 var doNext = function () { -1483 self.offset = 0; -1484 self.index++; -1485 if (self.index < self.blocks.length) { -1486 self.blocks[self.index].execute(function () { -1487 self._next(); -1488 }); -1489 } else { -1490 self.finish(); -1491 } -1492 }; -1493 var now = new Date().getTime(); -1494 if (this.env.updateInterval && now - this.env.lastUpdate > this.env.updateInterval) { -1495 this.env.lastUpdate = now; -1496 this.env.setTimeout(doNext, 0); -1497 } else { -1498 doNext(); -1499 } -1500 -1501 }; -1502 -1503 jasmine.Queue.prototype.finish = function () { -1504 this.running = false; -1505 if (this.onComplete) { -1506 this.onComplete(); -1507 } -1508 }; -1509 -1510 jasmine.Queue.prototype.results = function () { -1511 var results = new jasmine.NestedResults(); -1512 for (var i = 0; i < this.blocks.length; i++) { -1513 if (this.blocks[i].results) { -1514 results.addResult(this.blocks[i].results()); -1515 } -1516 } -1517 return results; -1518 }; -1519 -1520 -1521 /* JasmineReporters.reporter -1522 * Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to -1523 * descendants of this object to do something with the results (see json_reporter.js) -1524 */ -1525 jasmine.Reporters = {}; -1526 -1527 jasmine.Reporters.reporter = function(callbacks) { -1528 var that = { -1529 callbacks: callbacks || {}, -1530 -1531 doCallback: function(callback, results) { -1532 if (callback) { -1533 callback(results); -1534 } -1535 }, -1536 -1537 reportRunnerResults: function(runner) { -1538 that.doCallback(that.callbacks.runnerCallback, runner); -1539 }, -1540 reportSuiteResults: function(suite) { -1541 that.doCallback(that.callbacks.suiteCallback, suite); -1542 }, -1543 reportSpecResults: function(spec) { -1544 that.doCallback(that.callbacks.specCallback, spec); -1545 }, -1546 log: function (str) { -1547 if (console && console.log) console.log(str); -1548 } -1549 }; -1550 -1551 return that; -1552 }; -1553 -1554 /** -1555 * Runner -1556 * -1557 * @constructor -1558 * @param {jasmine.Env} env -1559 */ -1560 jasmine.Runner = function(env) { -1561 var self = this; -1562 self.env = env; -1563 self.queue = new jasmine.Queue(env); -1564 self.before_ = []; -1565 self.after_ = []; -1566 self.suites_ = []; -1567 }; +1436 jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { +1437 this.append('[ '); +1438 for (var i = 0; i < array.length; i++) { +1439 if (i > 0) { +1440 this.append(', '); +1441 } +1442 this.format(array[i]); +1443 } +1444 this.append(' ]'); +1445 }; +1446 +1447 jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { +1448 var self = this; +1449 this.append('{ '); +1450 var first = true; +1451 +1452 this.iterateObject(obj, function(property, isGetter) { +1453 if (first) { +1454 first = false; +1455 } else { +1456 self.append(', '); +1457 } +1458 +1459 self.append(property); +1460 self.append(' : '); +1461 if (isGetter) { +1462 self.append('<getter>'); +1463 } else { +1464 self.format(obj[property]); +1465 } +1466 }); +1467 +1468 this.append(' }'); +1469 }; +1470 +1471 jasmine.StringPrettyPrinter.prototype.append = function(value) { +1472 this.string += value; +1473 }; +1474 jasmine.Queue = function(env) { +1475 this.env = env; +1476 this.blocks = []; +1477 this.running = false; +1478 this.index = 0; +1479 this.offset = 0; +1480 }; +1481 +1482 jasmine.Queue.prototype.addBefore = function (block) { +1483 this.blocks.unshift(block); +1484 }; +1485 +1486 jasmine.Queue.prototype.add = function(block) { +1487 this.blocks.push(block); +1488 }; +1489 +1490 jasmine.Queue.prototype.insertNext = function (block) { +1491 this.blocks.splice((this.index + this.offset + 1), 0, block); +1492 this.offset++; +1493 }; +1494 +1495 jasmine.Queue.prototype.start = function(onComplete) { +1496 var self = this; +1497 self.running = true; +1498 self.onComplete = onComplete; +1499 if (self.blocks[0]) { +1500 self.blocks[0].execute(function () { +1501 self._next(); +1502 }); +1503 } else { +1504 self.finish(); +1505 } +1506 }; +1507 +1508 jasmine.Queue.prototype.isRunning = function () { +1509 return this.running; +1510 }; +1511 +1512 jasmine.Queue.prototype._next = function () { +1513 var self = this; +1514 var doNext = function () { +1515 self.offset = 0; +1516 self.index++; +1517 if (self.index < self.blocks.length) { +1518 self.blocks[self.index].execute(function () { +1519 self._next(); +1520 }); +1521 } else { +1522 self.finish(); +1523 } +1524 }; +1525 var now = new Date().getTime(); +1526 if (this.env.updateInterval && now - this.env.lastUpdate > this.env.updateInterval) { +1527 this.env.lastUpdate = now; +1528 this.env.setTimeout(doNext, 0); +1529 } else { +1530 doNext(); +1531 } +1532 +1533 }; +1534 +1535 jasmine.Queue.prototype.finish = function () { +1536 this.running = false; +1537 if (this.onComplete) { +1538 this.onComplete(); +1539 } +1540 }; +1541 +1542 jasmine.Queue.prototype.results = function () { +1543 var results = new jasmine.NestedResults(); +1544 for (var i = 0; i < this.blocks.length; i++) { +1545 if (this.blocks[i].results) { +1546 results.addResult(this.blocks[i].results()); +1547 } +1548 } +1549 return results; +1550 }; +1551 +1552 +1553 /* JasmineReporters.reporter +1554 * Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to +1555 * descendants of this object to do something with the results (see json_reporter.js) +1556 */ +1557 jasmine.Reporters = {}; +1558 +1559 jasmine.Reporters.reporter = function(callbacks) { +1560 var that = { +1561 callbacks: callbacks || {}, +1562 +1563 doCallback: function(callback, results) { +1564 if (callback) { +1565 callback(results); +1566 } +1567 }, 1568 -1569 jasmine.Runner.prototype.execute = function() { -1570 var self = this; -1571 if (self.env.reporter.reportRunnerStarting) { -1572 self.env.reporter.reportRunnerStarting(this); -1573 } -1574 self.queue.start(function () { -1575 self.finishCallback(); -1576 }); -1577 }; -1578 -1579 jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { -1580 beforeEachFunction.typeName = 'beforeEach'; -1581 this.before_.push(beforeEachFunction); -1582 }; -1583 -1584 jasmine.Runner.prototype.afterEach = function(afterEachFunction) { -1585 afterEachFunction.typeName = 'afterEach'; -1586 this.after_.push(afterEachFunction); -1587 }; -1588 -1589 -1590 jasmine.Runner.prototype.finishCallback = function() { -1591 this.env.reporter.reportRunnerResults(this); -1592 }; -1593 -1594 jasmine.Runner.prototype.addSuite = function(suite) { -1595 this.suites_.push(suite); -1596 }; -1597 -1598 jasmine.Runner.prototype.add = function(block) { -1599 if (block instanceof jasmine.Suite) { -1600 this.addSuite(block); -1601 } -1602 this.queue.add(block); -1603 }; -1604 -1605 /** @deprecated */ -1606 jasmine.Runner.prototype.getAllSuites = function() { -1607 return this.suites_; -1608 }; -1609 +1569 reportRunnerResults: function(runner) { +1570 that.doCallback(that.callbacks.runnerCallback, runner); +1571 }, +1572 reportSuiteResults: function(suite) { +1573 that.doCallback(that.callbacks.suiteCallback, suite); +1574 }, +1575 reportSpecResults: function(spec) { +1576 that.doCallback(that.callbacks.specCallback, spec); +1577 }, +1578 log: function (str) { +1579 if (console && console.log) console.log(str); +1580 } +1581 }; +1582 +1583 return that; +1584 }; +1585 +1586 /** +1587 * Runner +1588 * +1589 * @constructor +1590 * @param {jasmine.Env} env +1591 */ +1592 jasmine.Runner = function(env) { +1593 var self = this; +1594 self.env = env; +1595 self.queue = new jasmine.Queue(env); +1596 self.before_ = []; +1597 self.after_ = []; +1598 self.suites_ = []; +1599 }; +1600 +1601 jasmine.Runner.prototype.execute = function() { +1602 var self = this; +1603 if (self.env.reporter.reportRunnerStarting) { +1604 self.env.reporter.reportRunnerStarting(this); +1605 } +1606 self.queue.start(function () { +1607 self.finishCallback(); +1608 }); +1609 }; 1610 -1611 jasmine.Runner.prototype.suites = function() { -1612 return this.suites_; -1613 }; -1614 -1615 jasmine.Runner.prototype.results = function() { -1616 return this.queue.results(); -1617 }; -1618 -1619 /** @deprecated */ -1620 jasmine.Runner.prototype.getResults = function() { -1621 return this.queue.results(); -1622 }; -1623 /** -1624 * Internal representation of a Jasmine specification, or test. -1625 * -1626 * @constructor -1627 * @param {jasmine.Env} env -1628 * @param {jasmine.Suite} suite -1629 * @param {String} description -1630 */ -1631 jasmine.Spec = function(env, suite, description) { -1632 if (!env) { -1633 throw new Error('jasmine.Env() required'); -1634 } -1635 ; -1636 if (!suite) { -1637 throw new Error('jasmine.Suite() required'); -1638 } -1639 ; -1640 var spec = this; -1641 spec.id = env.nextSpecId ? env.nextSpecId() : null; -1642 spec.env = env; -1643 spec.suite = suite; -1644 spec.description = description; -1645 spec.queue = new jasmine.Queue(env); +1611 jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { +1612 beforeEachFunction.typeName = 'beforeEach'; +1613 this.before_.push(beforeEachFunction); +1614 }; +1615 +1616 jasmine.Runner.prototype.afterEach = function(afterEachFunction) { +1617 afterEachFunction.typeName = 'afterEach'; +1618 this.after_.push(afterEachFunction); +1619 }; +1620 +1621 +1622 jasmine.Runner.prototype.finishCallback = function() { +1623 this.env.reporter.reportRunnerResults(this); +1624 }; +1625 +1626 jasmine.Runner.prototype.addSuite = function(suite) { +1627 this.suites_.push(suite); +1628 }; +1629 +1630 jasmine.Runner.prototype.add = function(block) { +1631 if (block instanceof jasmine.Suite) { +1632 this.addSuite(block); +1633 } +1634 this.queue.add(block); +1635 }; +1636 +1637 /** @deprecated */ +1638 jasmine.Runner.prototype.getAllSuites = function() { +1639 return this.suites_; +1640 }; +1641 +1642 +1643 jasmine.Runner.prototype.suites = function() { +1644 return this.suites_; +1645 }; 1646 -1647 spec.afterCallbacks = []; -1648 spec.spies_ = []; -1649 -1650 spec.results_ = new jasmine.NestedResults(); -1651 spec.results_.description = description; -1652 spec.matchersClass = null; -1653 }; -1654 -1655 jasmine.Spec.prototype.getFullName = function() { -1656 return this.suite.getFullName() + ' ' + this.description + '.'; -1657 }; -1658 -1659 -1660 jasmine.Spec.prototype.results = function() { -1661 return this.results_; -1662 }; -1663 -1664 jasmine.Spec.prototype.log = function(message) { -1665 return this.results_.log(message); -1666 }; -1667 -1668 /** @deprecated */ -1669 jasmine.Spec.prototype.getResults = function() { -1670 return this.results_; -1671 }; -1672 -1673 jasmine.Spec.prototype.runs = function (func) { -1674 var block = new jasmine.Block(this.env, func, this); -1675 this.addToQueue(block); -1676 return this; -1677 }; +1647 jasmine.Runner.prototype.results = function() { +1648 return this.queue.results(); +1649 }; +1650 +1651 /** @deprecated */ +1652 jasmine.Runner.prototype.getResults = function() { +1653 return this.queue.results(); +1654 }; +1655 /** +1656 * Internal representation of a Jasmine specification, or test. +1657 * +1658 * @constructor +1659 * @param {jasmine.Env} env +1660 * @param {jasmine.Suite} suite +1661 * @param {String} description +1662 */ +1663 jasmine.Spec = function(env, suite, description) { +1664 if (!env) { +1665 throw new Error('jasmine.Env() required'); +1666 } +1667 ; +1668 if (!suite) { +1669 throw new Error('jasmine.Suite() required'); +1670 } +1671 ; +1672 var spec = this; +1673 spec.id = env.nextSpecId ? env.nextSpecId() : null; +1674 spec.env = env; +1675 spec.suite = suite; +1676 spec.description = description; +1677 spec.queue = new jasmine.Queue(env); 1678 -1679 jasmine.Spec.prototype.addToQueue = function (block) { -1680 if (this.queue.isRunning()) { -1681 this.queue.insertNext(block); -1682 } else { -1683 this.queue.add(block); -1684 } +1679 spec.afterCallbacks = []; +1680 spec.spies_ = []; +1681 +1682 spec.results_ = new jasmine.NestedResults(); +1683 spec.results_.description = description; +1684 spec.matchersClass = null; 1685 }; 1686 -1687 /** -1688 * @private -1689 * @deprecated -1690 */ -1691 jasmine.Spec.prototype.expects_that = function(actual) { -1692 return this.expect(actual); -1693 }; -1694 -1695 jasmine.Spec.prototype.expect = function(actual) { -1696 return new (this.getMatchersClass_())(this.env, actual, this.results_); -1697 }; -1698 -1699 jasmine.Spec.prototype.waits = function(timeout) { -1700 var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); -1701 this.addToQueue(waitsFunc); -1702 return this; +1687 jasmine.Spec.prototype.getFullName = function() { +1688 return this.suite.getFullName() + ' ' + this.description + '.'; +1689 }; +1690 +1691 +1692 jasmine.Spec.prototype.results = function() { +1693 return this.results_; +1694 }; +1695 +1696 jasmine.Spec.prototype.log = function(message) { +1697 return this.results_.log(message); +1698 }; +1699 +1700 /** @deprecated */ +1701 jasmine.Spec.prototype.getResults = function() { +1702 return this.results_; 1703 }; 1704 -1705 jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { -1706 var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); -1707 this.addToQueue(waitsForFunc); +1705 jasmine.Spec.prototype.runs = function (func) { +1706 var block = new jasmine.Block(this.env, func, this); +1707 this.addToQueue(block); 1708 return this; 1709 }; 1710 -1711 jasmine.Spec.prototype.fail = function (e) { -1712 this.results_.addResult(new jasmine.ExpectationResult(false, e ? jasmine.util.formatException(e) : null, null)); -1713 }; -1714 -1715 jasmine.Spec.prototype.getMatchersClass_ = function() { -1716 return this.matchersClass || jasmine.Matchers; +1711 jasmine.Spec.prototype.addToQueue = function (block) { +1712 if (this.queue.isRunning()) { +1713 this.queue.insertNext(block); +1714 } else { +1715 this.queue.add(block); +1716 } 1717 }; 1718 -1719 jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { -1720 var parent = this.getMatchersClass_(); -1721 var newMatchersClass = function() { -1722 parent.apply(this, arguments); -1723 }; -1724 jasmine.util.inherit(newMatchersClass, parent); -1725 for (var method in matchersPrototype) { -1726 newMatchersClass.prototype[method] = matchersPrototype[method]; -1727 } -1728 this.matchersClass = newMatchersClass; +1719 /** +1720 * @private +1721 * @deprecated +1722 */ +1723 jasmine.Spec.prototype.expects_that = function(actual) { +1724 return this.expect(actual); +1725 }; +1726 +1727 jasmine.Spec.prototype.expect = function(actual) { +1728 return new (this.getMatchersClass_())(this.env, actual, this.results_); 1729 }; 1730 -1731 jasmine.Spec.prototype.finishCallback = function() { -1732 this.env.reporter.reportSpecResults(this); -1733 }; -1734 -1735 jasmine.Spec.prototype.finish = function(onComplete) { -1736 this.removeAllSpies(); -1737 this.finishCallback(); -1738 if (onComplete) { -1739 onComplete(); -1740 } +1731 jasmine.Spec.prototype.waits = function(timeout) { +1732 var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); +1733 this.addToQueue(waitsFunc); +1734 return this; +1735 }; +1736 +1737 jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) { +1738 var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this); +1739 this.addToQueue(waitsForFunc); +1740 return this; 1741 }; 1742 -1743 jasmine.Spec.prototype.after = function(doAfter, test) { -1744 -1745 if (this.queue.isRunning()) { -1746 this.queue.add(new jasmine.Block(this.env, doAfter, this)); -1747 } else { -1748 this.afterCallbacks.unshift(doAfter); -1749 } -1750 }; -1751 -1752 jasmine.Spec.prototype.execute = function(onComplete) { -1753 var spec = this; -1754 if (!spec.env.specFilter(spec)) { -1755 spec.results_.skipped = true; -1756 spec.finish(onComplete); -1757 return; -1758 } -1759 this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...'); -1760 -1761 spec.env.currentSpec = spec; -1762 spec.env.currentlyRunningTests = true; -1763 -1764 spec.addBeforesAndAftersToQueue(); -1765 -1766 spec.queue.start(function () { -1767 spec.finish(onComplete); -1768 }); -1769 spec.env.currentlyRunningTests = false; -1770 }; -1771 -1772 jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { -1773 var runner = this.env.currentRunner(); -1774 for (var suite = this.suite; suite; suite = suite.parentSuite) { -1775 for (var i = 0; i < suite.before_.length; i++) { -1776 this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); -1777 } -1778 } -1779 for (var i = 0; i < runner.before_.length; i++) { -1780 this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); +1743 jasmine.Spec.prototype.fail = function (e) { +1744 this.results_.addResult(new jasmine.ExpectationResult(false, e ? jasmine.util.formatException(e) : null, null)); +1745 }; +1746 +1747 jasmine.Spec.prototype.getMatchersClass_ = function() { +1748 return this.matchersClass || jasmine.Matchers; +1749 }; +1750 +1751 jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { +1752 var parent = this.getMatchersClass_(); +1753 var newMatchersClass = function() { +1754 parent.apply(this, arguments); +1755 }; +1756 jasmine.util.inherit(newMatchersClass, parent); +1757 for (var method in matchersPrototype) { +1758 newMatchersClass.prototype[method] = matchersPrototype[method]; +1759 } +1760 this.matchersClass = newMatchersClass; +1761 }; +1762 +1763 jasmine.Spec.prototype.finishCallback = function() { +1764 this.env.reporter.reportSpecResults(this); +1765 }; +1766 +1767 jasmine.Spec.prototype.finish = function(onComplete) { +1768 this.removeAllSpies(); +1769 this.finishCallback(); +1770 if (onComplete) { +1771 onComplete(); +1772 } +1773 }; +1774 +1775 jasmine.Spec.prototype.after = function(doAfter, test) { +1776 +1777 if (this.queue.isRunning()) { +1778 this.queue.add(new jasmine.Block(this.env, doAfter, this)); +1779 } else { +1780 this.afterCallbacks.unshift(doAfter); 1781 } -1782 for (i = 0; i < this.afterCallbacks.length; i++) { -1783 this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); -1784 } -1785 for (suite = this.suite; suite; suite = suite.parentSuite) { -1786 for (var i = 0; i < suite.after_.length; i++) { -1787 this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); -1788 } -1789 } -1790 for (var i = 0; i < runner.after_.length; i++) { -1791 this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); -1792 } -1793 }; -1794 -1795 jasmine.Spec.prototype.explodes = function() { -1796 throw 'explodes function should not have been called'; -1797 }; -1798 -1799 jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { -1800 if (obj == undefined) { -1801 throw "spyOn could not find an object to spy upon for " + methodName + "()"; -1802 } +1782 }; +1783 +1784 jasmine.Spec.prototype.execute = function(onComplete) { +1785 var spec = this; +1786 if (!spec.env.specFilter(spec)) { +1787 spec.results_.skipped = true; +1788 spec.finish(onComplete); +1789 return; +1790 } +1791 this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...'); +1792 +1793 spec.env.currentSpec = spec; +1794 spec.env.currentlyRunningTests = true; +1795 +1796 spec.addBeforesAndAftersToQueue(); +1797 +1798 spec.queue.start(function () { +1799 spec.finish(onComplete); +1800 }); +1801 spec.env.currentlyRunningTests = false; +1802 }; 1803 -1804 if (!ignoreMethodDoesntExist && obj[methodName] === undefined) { -1805 throw methodName + '() method does not exist'; -1806 } -1807 -1808 if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { -1809 throw new Error(methodName + ' has already been spied upon'); +1804 jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { +1805 var runner = this.env.currentRunner(); +1806 for (var suite = this.suite; suite; suite = suite.parentSuite) { +1807 for (var i = 0; i < suite.before_.length; i++) { +1808 this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); +1809 } 1810 } -1811 -1812 var spyObj = jasmine.createSpy(methodName); -1813 -1814 this.spies_.push(spyObj); -1815 spyObj.baseObj = obj; -1816 spyObj.methodName = methodName; -1817 spyObj.originalValue = obj[methodName]; -1818 -1819 obj[methodName] = spyObj; -1820 -1821 return spyObj; -1822 }; -1823 -1824 jasmine.Spec.prototype.removeAllSpies = function() { -1825 for (var i = 0; i < this.spies_.length; i++) { -1826 var spy = this.spies_[i]; -1827 spy.baseObj[spy.methodName] = spy.originalValue; -1828 } -1829 this.spies_ = []; -1830 }; -1831 -1832 /** -1833 * Internal representation of a Jasmine suite. -1834 * -1835 * @constructor -1836 * @param {jasmine.Env} env -1837 * @param {String} description -1838 * @param {Function} specDefinitions -1839 * @param {jasmine.Suite} parentSuite -1840 */ -1841 jasmine.Suite = function(env, description, specDefinitions, parentSuite) { -1842 var self = this; -1843 self.id = env.nextSuiteId ? env.nextSuiteId() : null; -1844 self.description = description; -1845 self.queue = new jasmine.Queue(env); -1846 self.parentSuite = parentSuite; -1847 self.env = env; -1848 self.before_ = []; -1849 self.after_ = []; -1850 self.specs_ = []; -1851 }; +1811 for (var i = 0; i < runner.before_.length; i++) { +1812 this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); +1813 } +1814 for (i = 0; i < this.afterCallbacks.length; i++) { +1815 this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); +1816 } +1817 for (suite = this.suite; suite; suite = suite.parentSuite) { +1818 for (var i = 0; i < suite.after_.length; i++) { +1819 this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); +1820 } +1821 } +1822 for (var i = 0; i < runner.after_.length; i++) { +1823 this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); +1824 } +1825 }; +1826 +1827 jasmine.Spec.prototype.explodes = function() { +1828 throw 'explodes function should not have been called'; +1829 }; +1830 +1831 jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { +1832 if (obj == undefined) { +1833 throw "spyOn could not find an object to spy upon for " + methodName + "()"; +1834 } +1835 +1836 if (!ignoreMethodDoesntExist && obj[methodName] === undefined) { +1837 throw methodName + '() method does not exist'; +1838 } +1839 +1840 if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { +1841 throw new Error(methodName + ' has already been spied upon'); +1842 } +1843 +1844 var spyObj = jasmine.createSpy(methodName); +1845 +1846 this.spies_.push(spyObj); +1847 spyObj.baseObj = obj; +1848 spyObj.methodName = methodName; +1849 spyObj.originalValue = obj[methodName]; +1850 +1851 obj[methodName] = spyObj; 1852 -1853 jasmine.Suite.prototype.getFullName = function() { -1854 var fullName = this.description; -1855 for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { -1856 fullName = parentSuite.description + ' ' + fullName; -1857 } -1858 return fullName; -1859 }; -1860 -1861 jasmine.Suite.prototype.finish = function(onComplete) { -1862 this.env.reporter.reportSuiteResults(this); -1863 this.finished = true; -1864 if (typeof(onComplete) == 'function') { -1865 onComplete(); -1866 } -1867 }; -1868 -1869 jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { -1870 beforeEachFunction.typeName = 'beforeEach'; -1871 this.before_.push(beforeEachFunction); -1872 }; -1873 -1874 jasmine.Suite.prototype.afterEach = function(afterEachFunction) { -1875 afterEachFunction.typeName = 'afterEach'; -1876 this.after_.push(afterEachFunction); -1877 }; -1878 -1879 /** @deprecated */ -1880 jasmine.Suite.prototype.getResults = function() { -1881 return this.queue.results(); -1882 }; -1883 -1884 jasmine.Suite.prototype.results = function() { -1885 return this.queue.results(); -1886 }; -1887 -1888 jasmine.Suite.prototype.add = function(block) { -1889 if (block instanceof jasmine.Suite) { -1890 this.env.currentRunner().addSuite(block); -1891 } else { -1892 this.specs_.push(block); -1893 } -1894 this.queue.add(block); -1895 }; -1896 -1897 /** @deprecated */ -1898 jasmine.Suite.prototype.specCount = function() { -1899 return this.specs_.length; -1900 }; -1901 -1902 jasmine.Suite.prototype.specs = function() { -1903 return this.specs_; +1853 return spyObj; +1854 }; +1855 +1856 jasmine.Spec.prototype.removeAllSpies = function() { +1857 for (var i = 0; i < this.spies_.length; i++) { +1858 var spy = this.spies_[i]; +1859 spy.baseObj[spy.methodName] = spy.originalValue; +1860 } +1861 this.spies_ = []; +1862 }; +1863 +1864 /** +1865 * Internal representation of a Jasmine suite. +1866 * +1867 * @constructor +1868 * @param {jasmine.Env} env +1869 * @param {String} description +1870 * @param {Function} specDefinitions +1871 * @param {jasmine.Suite} parentSuite +1872 */ +1873 jasmine.Suite = function(env, description, specDefinitions, parentSuite) { +1874 var self = this; +1875 self.id = env.nextSuiteId ? env.nextSuiteId() : null; +1876 self.description = description; +1877 self.queue = new jasmine.Queue(env); +1878 self.parentSuite = parentSuite; +1879 self.env = env; +1880 self.before_ = []; +1881 self.after_ = []; +1882 self.specs_ = []; +1883 }; +1884 +1885 jasmine.Suite.prototype.getFullName = function() { +1886 var fullName = this.description; +1887 for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { +1888 fullName = parentSuite.description + ' ' + fullName; +1889 } +1890 return fullName; +1891 }; +1892 +1893 jasmine.Suite.prototype.finish = function(onComplete) { +1894 this.env.reporter.reportSuiteResults(this); +1895 this.finished = true; +1896 if (typeof(onComplete) == 'function') { +1897 onComplete(); +1898 } +1899 }; +1900 +1901 jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { +1902 beforeEachFunction.typeName = 'beforeEach'; +1903 this.before_.push(beforeEachFunction); 1904 }; 1905 -1906 jasmine.Suite.prototype.execute = function(onComplete) { -1907 var self = this; -1908 this.queue.start(function () { -1909 self.finish(onComplete); -1910 }); -1911 }; -1912 jasmine.WaitsBlock = function(env, timeout, spec) { -1913 this.timeout = timeout; -1914 jasmine.Block.call(this, env, null, spec); -1915 }; -1916 -1917 jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); -1918 -1919 jasmine.WaitsBlock.prototype.execute = function (onComplete) { -1920 this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); -1921 this.env.setTimeout(function () { -1922 onComplete(); -1923 }, this.timeout); -1924 }; -1925 jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { -1926 this.timeout = timeout; -1927 this.latchFunction = latchFunction; -1928 this.message = message; -1929 this.totalTimeSpentWaitingForLatch = 0; -1930 jasmine.Block.call(this, env, null, spec); -1931 }; -1932 -1933 jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); -1934 -1935 jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100; -1936 -1937 jasmine.WaitsForBlock.prototype.execute = function (onComplete) { -1938 var self = this; -1939 self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen')); -1940 var latchFunctionResult; -1941 try { -1942 latchFunctionResult = self.latchFunction.apply(self.spec); -1943 } catch (e) { -1944 self.spec.fail(e); -1945 onComplete(); -1946 return; -1947 } +1906 jasmine.Suite.prototype.afterEach = function(afterEachFunction) { +1907 afterEachFunction.typeName = 'afterEach'; +1908 this.after_.push(afterEachFunction); +1909 }; +1910 +1911 /** @deprecated */ +1912 jasmine.Suite.prototype.getResults = function() { +1913 return this.queue.results(); +1914 }; +1915 +1916 jasmine.Suite.prototype.results = function() { +1917 return this.queue.results(); +1918 }; +1919 +1920 jasmine.Suite.prototype.add = function(block) { +1921 if (block instanceof jasmine.Suite) { +1922 this.env.currentRunner().addSuite(block); +1923 } else { +1924 this.specs_.push(block); +1925 } +1926 this.queue.add(block); +1927 }; +1928 +1929 /** @deprecated */ +1930 jasmine.Suite.prototype.specCount = function() { +1931 return this.specs_.length; +1932 }; +1933 +1934 jasmine.Suite.prototype.specs = function() { +1935 return this.specs_; +1936 }; +1937 +1938 jasmine.Suite.prototype.execute = function(onComplete) { +1939 var self = this; +1940 this.queue.start(function () { +1941 self.finish(onComplete); +1942 }); +1943 }; +1944 jasmine.WaitsBlock = function(env, timeout, spec) { +1945 this.timeout = timeout; +1946 jasmine.Block.call(this, env, null, spec); +1947 }; 1948 -1949 if (latchFunctionResult) { -1950 onComplete(); -1951 } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) { -1952 var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen'); -1953 self.spec.fail({ -1954 name: 'timeout', -1955 message: message -1956 }); -1957 self.spec._next(); -1958 } else { -1959 self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; -1960 self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); -1961 } -1962 }; -1963 // Mock setTimeout, clearTimeout -1964 // Contributed by Pivotal Computer Systems, www.pivotalsf.com -1965 -1966 jasmine.FakeTimer = function() { -1967 this.reset(); -1968 -1969 var self = this; -1970 self.setTimeout = function(funcToCall, millis) { -1971 self.timeoutsMade++; -1972 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); -1973 return self.timeoutsMade; -1974 }; -1975 -1976 self.setInterval = function(funcToCall, millis) { -1977 self.timeoutsMade++; -1978 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); -1979 return self.timeoutsMade; -1980 }; -1981 -1982 self.clearTimeout = function(timeoutKey) { -1983 self.scheduledFunctions[timeoutKey] = undefined; -1984 }; -1985 -1986 self.clearInterval = function(timeoutKey) { -1987 self.scheduledFunctions[timeoutKey] = undefined; -1988 }; -1989 -1990 }; -1991 -1992 jasmine.FakeTimer.prototype.reset = function() { -1993 this.timeoutsMade = 0; -1994 this.scheduledFunctions = {}; -1995 this.nowMillis = 0; -1996 }; +1949 jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); +1950 +1951 jasmine.WaitsBlock.prototype.execute = function (onComplete) { +1952 this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); +1953 this.env.setTimeout(function () { +1954 onComplete(); +1955 }, this.timeout); +1956 }; +1957 jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { +1958 this.timeout = timeout; +1959 this.latchFunction = latchFunction; +1960 this.message = message; +1961 this.totalTimeSpentWaitingForLatch = 0; +1962 jasmine.Block.call(this, env, null, spec); +1963 }; +1964 +1965 jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); +1966 +1967 jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100; +1968 +1969 jasmine.WaitsForBlock.prototype.execute = function (onComplete) { +1970 var self = this; +1971 self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen')); +1972 var latchFunctionResult; +1973 try { +1974 latchFunctionResult = self.latchFunction.apply(self.spec); +1975 } catch (e) { +1976 self.spec.fail(e); +1977 onComplete(); +1978 return; +1979 } +1980 +1981 if (latchFunctionResult) { +1982 onComplete(); +1983 } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) { +1984 var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen'); +1985 self.spec.fail({ +1986 name: 'timeout', +1987 message: message +1988 }); +1989 self.spec._next(); +1990 } else { +1991 self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; +1992 self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); +1993 } +1994 }; +1995 // Mock setTimeout, clearTimeout +1996 // Contributed by Pivotal Computer Systems, www.pivotalsf.com 1997 -1998 jasmine.FakeTimer.prototype.tick = function(millis) { -1999 var oldMillis = this.nowMillis; -2000 var newMillis = oldMillis + millis; -2001 this.runFunctionsWithinRange(oldMillis, newMillis); -2002 this.nowMillis = newMillis; -2003 }; -2004 -2005 jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { -2006 var scheduledFunc; -2007 var funcsToRun = []; -2008 for (var timeoutKey in this.scheduledFunctions) { -2009 scheduledFunc = this.scheduledFunctions[timeoutKey]; -2010 if (scheduledFunc != undefined && -2011 scheduledFunc.runAtMillis >= oldMillis && -2012 scheduledFunc.runAtMillis <= nowMillis) { -2013 funcsToRun.push(scheduledFunc); -2014 this.scheduledFunctions[timeoutKey] = undefined; -2015 } -2016 } +1998 jasmine.FakeTimer = function() { +1999 this.reset(); +2000 +2001 var self = this; +2002 self.setTimeout = function(funcToCall, millis) { +2003 self.timeoutsMade++; +2004 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); +2005 return self.timeoutsMade; +2006 }; +2007 +2008 self.setInterval = function(funcToCall, millis) { +2009 self.timeoutsMade++; +2010 self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); +2011 return self.timeoutsMade; +2012 }; +2013 +2014 self.clearTimeout = function(timeoutKey) { +2015 self.scheduledFunctions[timeoutKey] = undefined; +2016 }; 2017 -2018 if (funcsToRun.length > 0) { -2019 funcsToRun.sort(function(a, b) { -2020 return a.runAtMillis - b.runAtMillis; -2021 }); -2022 for (var i = 0; i < funcsToRun.length; ++i) { -2023 try { -2024 var funcToRun = funcsToRun[i]; -2025 this.nowMillis = funcToRun.runAtMillis; -2026 funcToRun.funcToCall(); -2027 if (funcToRun.recurring) { -2028 this.scheduleFunction(funcToRun.timeoutKey, -2029 funcToRun.funcToCall, -2030 funcToRun.millis, -2031 true); -2032 } -2033 } catch(e) { -2034 } -2035 } -2036 this.runFunctionsWithinRange(oldMillis, nowMillis); -2037 } -2038 }; -2039 -2040 jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { -2041 this.scheduledFunctions[timeoutKey] = { -2042 runAtMillis: this.nowMillis + millis, -2043 funcToCall: funcToCall, -2044 recurring: recurring, -2045 timeoutKey: timeoutKey, -2046 millis: millis -2047 }; -2048 }; +2018 self.clearInterval = function(timeoutKey) { +2019 self.scheduledFunctions[timeoutKey] = undefined; +2020 }; +2021 +2022 }; +2023 +2024 jasmine.FakeTimer.prototype.reset = function() { +2025 this.timeoutsMade = 0; +2026 this.scheduledFunctions = {}; +2027 this.nowMillis = 0; +2028 }; +2029 +2030 jasmine.FakeTimer.prototype.tick = function(millis) { +2031 var oldMillis = this.nowMillis; +2032 var newMillis = oldMillis + millis; +2033 this.runFunctionsWithinRange(oldMillis, newMillis); +2034 this.nowMillis = newMillis; +2035 }; +2036 +2037 jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { +2038 var scheduledFunc; +2039 var funcsToRun = []; +2040 for (var timeoutKey in this.scheduledFunctions) { +2041 scheduledFunc = this.scheduledFunctions[timeoutKey]; +2042 if (scheduledFunc != undefined && +2043 scheduledFunc.runAtMillis >= oldMillis && +2044 scheduledFunc.runAtMillis <= nowMillis) { +2045 funcsToRun.push(scheduledFunc); +2046 this.scheduledFunctions[timeoutKey] = undefined; +2047 } +2048 } 2049 -2050 -2051 jasmine.Clock = { -2052 defaultFakeTimer: new jasmine.FakeTimer(), -2053 -2054 reset: function() { -2055 jasmine.Clock.assertInstalled(); -2056 jasmine.Clock.defaultFakeTimer.reset(); -2057 }, -2058 -2059 tick: function(millis) { -2060 jasmine.Clock.assertInstalled(); -2061 jasmine.Clock.defaultFakeTimer.tick(millis); -2062 }, -2063 -2064 runFunctionsWithinRange: function(oldMillis, nowMillis) { -2065 jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); -2066 }, -2067 -2068 scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { -2069 jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); -2070 }, +2050 if (funcsToRun.length > 0) { +2051 funcsToRun.sort(function(a, b) { +2052 return a.runAtMillis - b.runAtMillis; +2053 }); +2054 for (var i = 0; i < funcsToRun.length; ++i) { +2055 try { +2056 var funcToRun = funcsToRun[i]; +2057 this.nowMillis = funcToRun.runAtMillis; +2058 funcToRun.funcToCall(); +2059 if (funcToRun.recurring) { +2060 this.scheduleFunction(funcToRun.timeoutKey, +2061 funcToRun.funcToCall, +2062 funcToRun.millis, +2063 true); +2064 } +2065 } catch(e) { +2066 } +2067 } +2068 this.runFunctionsWithinRange(oldMillis, nowMillis); +2069 } +2070 }; 2071 -2072 useMock: function() { -2073 var spec = jasmine.getEnv().currentSpec; -2074 spec.after(jasmine.Clock.uninstallMock); -2075 -2076 jasmine.Clock.installMock(); -2077 }, -2078 -2079 installMock: function() { -2080 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; -2081 }, +2072 jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { +2073 this.scheduledFunctions[timeoutKey] = { +2074 runAtMillis: this.nowMillis + millis, +2075 funcToCall: funcToCall, +2076 recurring: recurring, +2077 timeoutKey: timeoutKey, +2078 millis: millis +2079 }; +2080 }; +2081 2082 -2083 uninstallMock: function() { -2084 jasmine.Clock.assertInstalled(); -2085 jasmine.Clock.installed = jasmine.Clock.real; -2086 }, -2087 -2088 real: { -2089 setTimeout: window.setTimeout, -2090 clearTimeout: window.clearTimeout, -2091 setInterval: window.setInterval, -2092 clearInterval: window.clearInterval -2093 }, -2094 -2095 assertInstalled: function() { -2096 if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) { -2097 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); -2098 } -2099 }, -2100 -2101 installed: null -2102 }; -2103 jasmine.Clock.installed = jasmine.Clock.real; -2104 -2105 window.setTimeout = function(funcToCall, millis) { -2106 return jasmine.Clock.installed.setTimeout.apply(this, arguments); -2107 }; -2108 -2109 window.setInterval = function(funcToCall, millis) { -2110 return jasmine.Clock.installed.setInterval.apply(this, arguments); -2111 }; -2112 -2113 window.clearTimeout = function(timeoutKey) { -2114 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); -2115 }; -2116 -2117 window.clearInterval = function(timeoutKey) { -2118 return jasmine.Clock.installed.clearInterval.apply(this, arguments); -2119 }; -2120 -2121 \ No newline at end of file +2083 jasmine.Clock = { +2084 defaultFakeTimer: new jasmine.FakeTimer(), +2085 +2086 reset: function() { +2087 jasmine.Clock.assertInstalled(); +2088 jasmine.Clock.defaultFakeTimer.reset(); +2089 }, +2090 +2091 tick: function(millis) { +2092 jasmine.Clock.assertInstalled(); +2093 jasmine.Clock.defaultFakeTimer.tick(millis); +2094 }, +2095 +2096 runFunctionsWithinRange: function(oldMillis, nowMillis) { +2097 jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); +2098 }, +2099 +2100 scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { +2101 jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); +2102 }, +2103 +2104 useMock: function() { +2105 var spec = jasmine.getEnv().currentSpec; +2106 spec.after(jasmine.Clock.uninstallMock); +2107 +2108 jasmine.Clock.installMock(); +2109 }, +2110 +2111 installMock: function() { +2112 jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; +2113 }, +2114 +2115 uninstallMock: function() { +2116 jasmine.Clock.assertInstalled(); +2117 jasmine.Clock.installed = jasmine.Clock.real; +2118 }, +2119 +2120 real: { +2121 setTimeout: window.setTimeout, +2122 clearTimeout: window.clearTimeout, +2123 setInterval: window.setInterval, +2124 clearInterval: window.clearInterval +2125 }, +2126 +2127 assertInstalled: function() { +2128 if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) { +2129 throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); +2130 } +2131 }, +2132 +2133 installed: null +2134 }; +2135 jasmine.Clock.installed = jasmine.Clock.real; +2136 +2137 window.setTimeout = function(funcToCall, millis) { +2138 return jasmine.Clock.installed.setTimeout.apply(this, arguments); +2139 }; +2140 +2141 window.setInterval = function(funcToCall, millis) { +2142 return jasmine.Clock.installed.setInterval.apply(this, arguments); +2143 }; +2144 +2145 window.clearTimeout = function(timeoutKey) { +2146 return jasmine.Clock.installed.clearTimeout.apply(this, arguments); +2147 }; +2148 +2149 window.clearInterval = function(timeoutKey) { +2150 return jasmine.Clock.installed.clearInterval.apply(this, arguments); +2151 }; +2152 +2153 \ No newline at end of file diff --git a/doc/symbols/src/lib_json2.js.html b/doc/symbols/src/lib_json2.js.html index 59b08d2..c2095e2 100644 --- a/doc/symbols/src/lib_json2.js.html +++ b/doc/symbols/src/lib_json2.js.html @@ -7,7 +7,7 @@ .line {border-right: 1px dotted #666; color: #666; font-style: normal;}
  1 /*
   2     http://www.JSON.org/json2.js
-  3     2008-11-19
+  3     2009-08-17
   4 
   5     Public Domain.
   6 
@@ -40,7 +40,7 @@
  33             value represented by the name/value pair that should be serialized,
  34             or undefined if nothing should be serialized. The toJSON method
  35             will be passed the key associated with the value, and this will be
- 36             bound to the object holding the key.
+ 36             bound to the value
  37 
  38             For example, this would serialize Dates as ISO strings.
  39 
@@ -153,212 +153,212 @@
 146 
 147 /*jslint evil: true */
 148 
-149 /*global JSON */
-150 
-151 /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
-152     call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
-153     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
-154     lastIndex, length, parse, prototype, push, replace, slice, stringify,
-155     test, toJSON, toString, valueOf
-156 */
+149 /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+150     call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+151     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+152     lastIndex, length, parse, prototype, push, replace, slice, stringify,
+153     test, toJSON, toString, valueOf
+154 */
+155 
+156 "use strict";
 157 
 158 // Create a JSON object only if one does not already exist. We create the
 159 // methods in a closure to avoid creating global variables.
 160 
 161 if (!this.JSON) {
-162     JSON = {};
+162     this.JSON = {};
 163 }
-164 (function () {
-165 
-166     function f(n) {
-167         // Format integers to have at least two digits.
-168         return n < 10 ? '0' + n : n;
-169     }
-170 
-171     if (typeof Date.prototype.toJSON !== 'function') {
-172 
-173         Date.prototype.toJSON = function (key) {
-174 
-175             return this.getUTCFullYear()   + '-' +
-176                  f(this.getUTCMonth() + 1) + '-' +
-177                  f(this.getUTCDate())      + 'T' +
-178                  f(this.getUTCHours())     + ':' +
-179                  f(this.getUTCMinutes())   + ':' +
-180                  f(this.getUTCSeconds())   + 'Z';
-181         };
-182 
-183         String.prototype.toJSON =
-184         Number.prototype.toJSON =
-185         Boolean.prototype.toJSON = function (key) {
-186             return this.valueOf();
-187         };
-188     }
-189 
-190     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-191         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
-192         gap,
-193         indent,
-194         meta = {    // table of character substitutions
-195             '\b': '\\b',
-196             '\t': '\\t',
-197             '\n': '\\n',
-198             '\f': '\\f',
-199             '\r': '\\r',
-200             '"' : '\\"',
-201             '\\': '\\\\'
-202         },
-203         rep;
-204 
-205 
-206     function quote(string) {
+164 
+165 (function () {
+166 
+167     function f(n) {
+168         // Format integers to have at least two digits.
+169         return n < 10 ? '0' + n : n;
+170     }
+171 
+172     if (typeof Date.prototype.toJSON !== 'function') {
+173 
+174         Date.prototype.toJSON = function (key) {
+175 
+176             return isFinite(this.valueOf()) ?
+177                    this.getUTCFullYear()   + '-' +
+178                  f(this.getUTCMonth() + 1) + '-' +
+179                  f(this.getUTCDate())      + 'T' +
+180                  f(this.getUTCHours())     + ':' +
+181                  f(this.getUTCMinutes())   + ':' +
+182                  f(this.getUTCSeconds())   + 'Z' : null;
+183         };
+184 
+185         String.prototype.toJSON =
+186         Number.prototype.toJSON =
+187         Boolean.prototype.toJSON = function (key) {
+188             return this.valueOf();
+189         };
+190     }
+191 
+192     var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+193         escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+194         gap,
+195         indent,
+196         meta = {    // table of character substitutions
+197             '\b': '\\b',
+198             '\t': '\\t',
+199             '\n': '\\n',
+200             '\f': '\\f',
+201             '\r': '\\r',
+202             '"' : '\\"',
+203             '\\': '\\\\'
+204         },
+205         rep;
+206 
 207 
-208 // If the string contains no control characters, no quote characters, and no
-209 // backslash characters, then we can safely slap some quotes around it.
-210 // Otherwise we must also replace the offending characters with safe escape
-211 // sequences.
-212 
-213         escapable.lastIndex = 0;
-214         return escapable.test(string) ?
-215             '"' + string.replace(escapable, function (a) {
-216                 var c = meta[a];
-217                 return typeof c === 'string' ? c :
-218                     '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
-219             }) + '"' :
-220             '"' + string + '"';
-221     }
-222 
-223 
-224     function str(key, holder) {
+208     function quote(string) {
+209 
+210 // If the string contains no control characters, no quote characters, and no
+211 // backslash characters, then we can safely slap some quotes around it.
+212 // Otherwise we must also replace the offending characters with safe escape
+213 // sequences.
+214 
+215         escapable.lastIndex = 0;
+216         return escapable.test(string) ?
+217             '"' + string.replace(escapable, function (a) {
+218                 var c = meta[a];
+219                 return typeof c === 'string' ? c :
+220                     '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+221             }) + '"' :
+222             '"' + string + '"';
+223     }
+224 
 225 
-226 // Produce a string from holder[key].
-227 
-228         var i,          // The loop counter.
-229             k,          // The member key.
-230             v,          // The member value.
-231             length,
-232             mind = gap,
-233             partial,
-234             value = holder[key];
-235 
-236 // If the value has a toJSON method, call it to obtain a replacement value.
-237 
-238         if (value && typeof value === 'object' &&
-239                 typeof value.toJSON === 'function') {
-240             value = value.toJSON(key);
-241         }
-242 
-243 // If we were called with a replacer function, then call the replacer to
-244 // obtain a replacement value.
-245 
-246         if (typeof rep === 'function') {
-247             value = rep.call(holder, key, value);
-248         }
-249 
-250 // What happens next depends on the value's type.
-251 
-252         switch (typeof value) {
-253         case 'string':
-254             return quote(value);
-255 
-256         case 'number':
-257 
-258 // JSON numbers must be finite. Encode non-finite numbers as null.
-259 
-260             return isFinite(value) ? String(value) : 'null';
-261 
-262         case 'boolean':
-263         case 'null':
-264 
-265 // If the value is a boolean or null, convert it to a string. Note:
-266 // typeof null does not produce 'null'. The case is included here in
-267 // the remote chance that this gets fixed someday.
-268 
-269             return String(value);
-270 
-271 // If the type is 'object', we might be dealing with an object or an array or
-272 // null.
-273 
-274         case 'object':
-275 
-276 // Due to a specification blunder in ECMAScript, typeof null is 'object',
-277 // so watch out for that case.
-278 
-279             if (!value) {
-280                 return 'null';
-281             }
-282 
-283 // Make an array to hold the partial results of stringifying this object value.
-284 
-285             gap += indent;
-286             partial = [];
-287 
-288 // Is the value an array?
-289 
-290             if (Object.prototype.toString.apply(value) === '[object Array]') {
-291 
-292 // The value is an array. Stringify every element. Use null as a placeholder
-293 // for non-JSON values.
-294 
-295                 length = value.length;
-296                 for (i = 0; i < length; i += 1) {
-297                     partial[i] = str(i, value) || 'null';
-298                 }
-299 
-300 // Join all of the elements together, separated with commas, and wrap them in
-301 // brackets.
-302 
-303                 v = partial.length === 0 ? '[]' :
-304                     gap ? '[\n' + gap +
-305                             partial.join(',\n' + gap) + '\n' +
-306                                 mind + ']' :
-307                           '[' + partial.join(',') + ']';
-308                 gap = mind;
-309                 return v;
-310             }
-311 
-312 // If the replacer is an array, use it to select the members to be stringified.
-313 
-314             if (rep && typeof rep === 'object') {
-315                 length = rep.length;
-316                 for (i = 0; i < length; i += 1) {
-317                     k = rep[i];
-318                     if (typeof k === 'string') {
-319                         v = str(k, value);
-320                         if (v) {
-321                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
-322                         }
-323                     }
-324                 }
-325             } else {
-326 
-327 // Otherwise, iterate through all of the keys in the object.
-328 
-329                 for (k in value) {
-330                     if (Object.hasOwnProperty.call(value, k)) {
-331                         v = str(k, value);
-332                         if (v) {
-333                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
-334                         }
-335                     }
-336                 }
-337             }
-338 
-339 // Join all of the member texts together, separated with commas,
-340 // and wrap them in braces.
-341 
-342             v = partial.length === 0 ? '{}' :
-343                 gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
-344                         mind + '}' : '{' + partial.join(',') + '}';
-345             gap = mind;
-346             return v;
-347         }
-348     }
-349 
-350 // If the JSON object does not yet have a stringify method, give it one.
-351 
-352     if (typeof JSON.stringify !== 'function') {
-353         JSON.stringify = function (value, replacer, space) {
-354 
+226     function str(key, holder) {
+227 // Produce a string from holder[key].
+228 
+229         var i,          // The loop counter.
+230             k,          // The member key.
+231             v,          // The member value.
+232             length,
+233             mind = gap,
+234             partial,
+235             value = holder[key];
+236 
+237 // If the value has a toJSON method, call it to obtain a replacement value.
+238 
+239         if (value && typeof value === 'object' &&
+240                 typeof value.toJSON === 'function') {
+241             value = value.toJSON(key);
+242         }
+243 
+244 // If we were called with a replacer function, then call the replacer to
+245 // obtain a replacement value.
+246 
+247         if (typeof rep === 'function') {
+248             value = rep.call(holder, key, value);
+249         }
+250 
+251 // What happens next depends on the value's type.
+252 
+253         switch (typeof value) {
+254         case 'string':
+255             return quote(value);
+256 
+257         case 'number':
+258 
+259 // JSON numbers must be finite. Encode non-finite numbers as null.
+260 
+261             return isFinite(value) ? String(value) : 'null';
+262 
+263         case 'boolean':
+264         case 'null':
+265 
+266 // If the value is a boolean or null, convert it to a string. Note:
+267 // typeof null does not produce 'null'. The case is included here in
+268 // the remote chance that this gets fixed someday.
+269 
+270             return String(value);
+271 
+272 // If the type is 'object', we might be dealing with an object or an array or
+273 // null.
+274 
+275         case 'object':
+276 
+277 // Due to a specification blunder in ECMAScript, typeof null is 'object',
+278 // so watch out for that case.
+279 
+280             if (!value) {
+281                 return 'null';
+282             }
+283 
+284 // Make an array to hold the partial results of stringifying this object value.
+285 
+286             gap += indent;
+287             partial = [];
+288 
+289 // Is the value an array?
+290 
+291             if (Object.prototype.toString.apply(value) === '[object Array]') {
+292 
+293 // The value is an array. Stringify every element. Use null as a placeholder
+294 // for non-JSON values.
+295 
+296                 length = value.length;
+297                 for (i = 0; i < length; i += 1) {
+298                     partial[i] = str(i, value) || 'null';
+299                 }
+300 
+301 // Join all of the elements together, separated with commas, and wrap them in
+302 // brackets.
+303 
+304                 v = partial.length === 0 ? '[]' :
+305                     gap ? '[\n' + gap +
+306                             partial.join(',\n' + gap) + '\n' +
+307                                 mind + ']' :
+308                           '[' + partial.join(',') + ']';
+309                 gap = mind;
+310                 return v;
+311             }
+312 
+313 // If the replacer is an array, use it to select the members to be stringified.
+314 
+315             if (rep && typeof rep === 'object') {
+316                 length = rep.length;
+317                 for (i = 0; i < length; i += 1) {
+318                     k = rep[i];
+319                     if (typeof k === 'string') {
+320                         v = str(k, value);
+321                         if (v) {
+322                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
+323                         }
+324                     }
+325                 }
+326             } else {
+327 
+328 // Otherwise, iterate through all of the keys in the object.
+329 
+330                 for (k in value) {
+331                     if (Object.hasOwnProperty.call(value, k)) {
+332                         v = str(k, value);
+333                         if (v) {
+334                             partial.push(quote(k) + (gap ? ': ' : ':') + v);
+335                         }
+336                     }
+337                 }
+338             }
+339 
+340 // Join all of the member texts together, separated with commas,
+341 // and wrap them in braces.
+342 
+343             v = partial.length === 0 ? '{}' :
+344                 gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
+345                         mind + '}' : '{' + partial.join(',') + '}';
+346             gap = mind;
+347             return v;
+348         }
+349     }
+350 
+351 // If the JSON object does not yet have a stringify method, give it one.
+352 
+353     if (typeof JSON.stringify !== 'function') {
+354         JSON.stringify = function (value, replacer, space) {
 355 // The stringify method takes a value and an optional replacer, and an optional
 356 // space parameter, and returns a JSON text. The replacer can be a function
 357 // that can replace values, or an array of strings that will select the keys.
@@ -482,5 +482,5 @@
 475             throw new SyntaxError('JSON.parse');
 476         };
 477     }
-478 })();
+478 }());
 479 
\ No newline at end of file diff --git a/lib/TrivialReporter.js b/lib/TrivialReporter.js index 20a209c..13cd3bc 100644 --- a/lib/TrivialReporter.js +++ b/lib/TrivialReporter.js @@ -12,7 +12,7 @@ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarA if (typeof child === 'string') { el.appendChild(document.createTextNode(child)); } else { - el.appendChild(child); + if (child) { el.appendChild(child); } } } diff --git a/lib/jasmine-0.9.0.js b/lib/jasmine-0.9.0.js index 8dcfb8c..c44d73a 100644 --- a/lib/jasmine-0.9.0.js +++ b/lib/jasmine-0.9.0.js @@ -517,7 +517,7 @@ jasmine.version_= { "major": 0, "minor": 9, "build": 0, - "revision": 1254180093 + "revision": 1254287286 }; /** * @namespace @@ -924,6 +924,38 @@ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { jasmine.JsApiReporter.prototype.log = function(str) { }; +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + for (var messageIndex in result.messages) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.text, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined + } + }); + }; + + var summaryResult = { + result : result.result, + messages : summaryMessages + }; + + return summaryResult; +}; + jasmine.Matchers = function(env, actual, results) { this.env = env; this.actual = actual; diff --git a/lib/json2.js b/lib/json2.js index 241a271..ac58079 100644 --- a/lib/json2.js +++ b/lib/json2.js @@ -1,6 +1,6 @@ /* http://www.JSON.org/json2.js - 2008-11-19 + 2009-08-17 Public Domain. @@ -33,7 +33,7 @@ value represented by the name/value pair that should be serialized, or undefined if nothing should be serialized. The toJSON method will be passed the key associated with the value, and this will be - bound to the object holding the key. + bound to the value For example, this would serialize Dates as ISO strings. @@ -146,8 +146,6 @@ /*jslint evil: true */ -/*global JSON */ - /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, @@ -155,12 +153,15 @@ test, toJSON, toString, valueOf */ +"use strict"; + // Create a JSON object only if one does not already exist. We create the // methods in a closure to avoid creating global variables. if (!this.JSON) { - JSON = {}; + this.JSON = {}; } + (function () { function f(n) { @@ -172,12 +173,13 @@ if (!this.JSON) { Date.prototype.toJSON = function (key) { - return this.getUTCFullYear() + '-' + + return isFinite(this.valueOf()) ? + this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + - f(this.getUTCSeconds()) + 'Z'; + f(this.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = @@ -222,7 +224,6 @@ if (!this.JSON) { function str(key, holder) { - // Produce a string from holder[key]. var i, // The loop counter. @@ -351,7 +352,6 @@ if (!this.JSON) { if (typeof JSON.stringify !== 'function') { JSON.stringify = function (value, replacer, space) { - // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function // that can replace values, or an array of strings that will select the keys. @@ -475,4 +475,4 @@ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { throw new SyntaxError('JSON.parse'); }; } -})(); +}()); diff --git a/spec/suites/JsApiReporterSpec.js b/spec/suites/JsApiReporterSpec.js index 68cfef5..ab29b1e 100644 --- a/spec/suites/JsApiReporterSpec.js +++ b/spec/suites/JsApiReporterSpec.js @@ -1,13 +1,13 @@ -describe('JsApiReporterSpec', function () { +describe('jasmine.jsApiReporter', function() { describe('results', function () { - var reporter, spec1, spec2, expectedSpec1Results, expectedSpec2Results; + var reporter, spec1, spec2, spec3, expectedSpec1Results, expectedSpec2Results; beforeEach(function() { var env = new jasmine.Env(); var suite = new jasmine.Suite(env); - spec1 = new jasmine.Spec(env, suite); + spec1 = new jasmine.Spec(env, suite, 'spec 1'); spec1.runs(function () { this.expect(true).toEqual(true); }); @@ -15,7 +15,7 @@ describe('JsApiReporterSpec', function () { messages: spec1.results().getItems(), result: "passed" }; - spec2 = new jasmine.Spec(env, suite); + spec2 = new jasmine.Spec(env, suite, 'spec 2'); spec2.runs(function () { this.expect(true).toEqual(false); }); @@ -24,12 +24,19 @@ describe('JsApiReporterSpec', function () { result: "failed" }; + spec3 = new jasmine.Spec(env, suite, 'spec 3'); + spec3.runs(function () { + this.log('some debug message') + }); + spec1.execute(); spec2.execute(); + spec3.execute(); reporter = new jasmine.JsApiReporter(); reporter.reportSpecResults(spec1); reporter.reportSpecResults(spec2); + reporter.reportSpecResults(spec3); }); it('resultForSpec() should return the result for the given spec', function () { @@ -43,5 +50,32 @@ describe('JsApiReporterSpec', function () { expect(reporter.results()[spec2.id]).toEqual(expectedSpec2Results); }); + describe("#summarizeResult_", function() { + it("should summarize a passing result", function() { + var result = reporter.results()[spec1.id]; + var summarizedResult = reporter.summarizeResult_(result); + expect(summarizedResult.result).toEqual('passed'); + expect(summarizedResult.messages.length).toEqual(1); + expect(summarizedResult.messages[0].message).toEqual(result.messages[0].message); + expect(summarizedResult.messages[0].passed).toBeTruthy(); + expect(summarizedResult.messages[0].type).toEqual('ExpectationResult'); + expect(summarizedResult.messages[0].text).toEqual(undefined); + expect(summarizedResult.messages[0].trace.stack).toEqual(undefined); + }); + + it("should have a stack trace for failing specs", function() { + var result = reporter.results()[spec2.id]; + var summarizedResult = reporter.summarizeResult_(result); + expect(summarizedResult.result).toEqual('failed'); + expect(summarizedResult.messages[0].trace.stack).toEqual(result.messages[0].trace.stack); + }); + + it("should have messages for specs with messages", function() { + var result = reporter.results()[spec3.id]; + var summarizedResult = reporter.summarizeResult_(result); + expect(summarizedResult.result).toEqual('passed'); + expect(summarizedResult.messages[0].text).toEqual('some debug message'); + }); + }); }); }); \ No newline at end of file diff --git a/src/JsApiReporter.js b/src/JsApiReporter.js index 9003cf9..9648826 100644 --- a/src/JsApiReporter.js +++ b/src/JsApiReporter.js @@ -68,3 +68,35 @@ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { jasmine.JsApiReporter.prototype.log = function(str) { }; +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + for (var messageIndex in result.messages) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.text, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined + } + }); + }; + + var summaryResult = { + result : result.result, + messages : summaryMessages + }; + + return summaryResult; +}; +