honkster-jelly 0.9.1 → 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +1 -2
  3. data/Gemfile.lock +1 -1
  4. data/Rakefile +0 -16
  5. data/jelly.gemspec +13 -64
  6. data/lib/jelly/jelly_helper.rb +1 -1
  7. data/spec/fixtures/public/javascripts/components/component1.js +0 -0
  8. data/spec/fixtures/public/javascripts/foo/components/paw.js +0 -0
  9. data/spec/fixtures/public/javascripts/foo/components/teeth.js +0 -0
  10. data/spec/fixtures/public/javascripts/foo/pages/bears.js +0 -0
  11. data/spec/fixtures/public/javascripts/foo/pages/lions.js +0 -0
  12. data/spec/fixtures/public/javascripts/foo/pages/tigers.js +0 -0
  13. data/spec/fixtures/public/javascripts/pages/page1.js +0 -0
  14. data/spec/jasmine/TrivialReporter.js +129 -0
  15. data/spec/jasmine/jasmine-0.10.0.js +2149 -0
  16. data/spec/jasmine/jasmine.css +76 -0
  17. data/spec/jasmine/json2.js +478 -0
  18. data/spec/jasmine_runner.html +30 -0
  19. data/spec/javascript/ajax_with_jelly_spec.js +157 -0
  20. data/spec/javascript/jelly_spec.js +649 -0
  21. data/spec/javascript/spec_helper.js +7 -0
  22. data/spec/jelly/common_spec.rb +56 -0
  23. data/spec/jelly/jelly_controller_spec.rb +331 -0
  24. data/spec/jelly/jelly_helper_spec.rb +88 -0
  25. data/spec/rails_root/Gemfile +31 -0
  26. data/spec/rails_root/Gemfile.lock +73 -0
  27. data/spec/rails_root/README +256 -0
  28. data/spec/rails_root/Rakefile +7 -0
  29. data/spec/rails_root/app/controllers/application_controller.rb +3 -0
  30. data/spec/rails_root/app/helpers/application_helper.rb +2 -0
  31. data/spec/rails_root/app/views/layouts/application.html.erb +14 -0
  32. data/spec/rails_root/config.ru +4 -0
  33. data/spec/rails_root/config/application.rb +42 -0
  34. data/spec/rails_root/config/boot.rb +6 -0
  35. data/spec/rails_root/config/database.yml +22 -0
  36. data/spec/rails_root/config/environment.rb +5 -0
  37. data/spec/rails_root/config/environments/development.rb +26 -0
  38. data/spec/rails_root/config/environments/production.rb +49 -0
  39. data/spec/rails_root/config/environments/test.rb +35 -0
  40. data/spec/rails_root/config/initializers/backtrace_silencers.rb +7 -0
  41. data/spec/rails_root/config/initializers/inflections.rb +10 -0
  42. data/spec/rails_root/config/initializers/mime_types.rb +5 -0
  43. data/spec/rails_root/config/initializers/new_rails_defaults.rb +19 -0
  44. data/spec/rails_root/config/initializers/secret_token.rb +7 -0
  45. data/spec/rails_root/config/initializers/session_store.rb +8 -0
  46. data/spec/rails_root/config/locales/en.yml +5 -0
  47. data/spec/rails_root/config/routes.rb +58 -0
  48. data/spec/rails_root/db/seeds.rb +7 -0
  49. data/spec/rails_root/db/test.sqlite3 +1 -0
  50. data/spec/rails_root/doc/README_FOR_APP +2 -0
  51. data/spec/rails_root/log/development.log +0 -0
  52. data/spec/rails_root/log/production.log +0 -0
  53. data/spec/rails_root/log/server.log +0 -0
  54. data/spec/rails_root/log/test.log +6 -0
  55. data/spec/rails_root/public/404.html +26 -0
  56. data/spec/rails_root/public/422.html +26 -0
  57. data/spec/rails_root/public/500.html +26 -0
  58. data/spec/rails_root/public/favicon.ico +0 -0
  59. data/spec/rails_root/public/images/rails.png +0 -0
  60. data/spec/rails_root/public/index.html +239 -0
  61. data/spec/rails_root/public/javascripts/application.js +2 -0
  62. data/spec/rails_root/public/javascripts/controls.js +965 -0
  63. data/spec/rails_root/public/javascripts/dragdrop.js +974 -0
  64. data/spec/rails_root/public/javascripts/effects.js +1123 -0
  65. data/spec/rails_root/public/javascripts/prototype.js +6001 -0
  66. data/spec/rails_root/public/javascripts/rails.js +191 -0
  67. data/spec/rails_root/public/robots.txt +5 -0
  68. data/spec/rails_root/script/about +4 -0
  69. data/spec/rails_root/script/console +3 -0
  70. data/spec/rails_root/script/dbconsole +3 -0
  71. data/spec/rails_root/script/destroy +3 -0
  72. data/spec/rails_root/script/generate +3 -0
  73. data/spec/rails_root/script/performance/benchmarker +3 -0
  74. data/spec/rails_root/script/performance/profiler +3 -0
  75. data/spec/rails_root/script/plugin +3 -0
  76. data/spec/rails_root/script/rails +6 -0
  77. data/spec/rails_root/script/runner +3 -0
  78. data/spec/rails_root/script/server +3 -0
  79. data/spec/rails_root/test/performance/browsing_test.rb +9 -0
  80. data/spec/rails_root/test/test_helper.rb +13 -0
  81. data/spec/spec_helper.rb +37 -0
  82. data/spec/spec_suite.rb +3 -0
  83. metadata +271 -46
  84. data/VERSION.yml +0 -5
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ .idea
2
+ *.svn
3
+ pkg
4
+ b
data/Gemfile CHANGED
@@ -1,10 +1,9 @@
1
1
  source :rubygems
2
2
 
3
- gem "rails", ">=3.0.0"
4
-
5
3
  group :test do
6
4
  gem "capybara", "0.4.1.2"
7
5
  gem "jeweler", "1.6.2"
6
+ gem "rails", "3.0.8"
8
7
  gem "rake", "0.9.2"
9
8
  gem "rr", "1.0.2"
10
9
  gem "rspec", "2.6.0"
data/Gemfile.lock CHANGED
@@ -115,7 +115,7 @@ PLATFORMS
115
115
  DEPENDENCIES
116
116
  capybara (= 0.4.1.2)
117
117
  jeweler (= 1.6.2)
118
- rails (>= 3.0.0)
118
+ rails (= 3.0.8)
119
119
  rake (= 0.9.2)
120
120
  rr (= 1.0.2)
121
121
  rspec (= 2.6.0)
data/Rakefile CHANGED
@@ -21,19 +21,3 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
21
21
  rdoc.rdoc_files.include('README')
22
22
  rdoc.rdoc_files.include('lib/**/*.rb')
23
23
  end
24
-
25
- begin
26
- require 'jeweler'
27
- Jeweler::Tasks.new do |gemspec|
28
- gemspec.name = ENV["GEM_PREFIX"] ? "#{ENV["GEM_PREFIX"]}-jelly" : "jelly"
29
- gemspec.summary = "a sweet unobtrusive javascript framework for jQuery and Rails"
30
- gemspec.description = "Jelly provides a set of tools and conventions for creating rich ajax/javascript web applications with jQuery and Ruby on Rails."
31
- gemspec.email = "opensource@pivotallabs.com"
32
- gemspec.homepage = "http://github.com/pivotal/jelly"
33
- gemspec.authors = ["Pivotal Labs, Inc"]
34
- gemspec.files.exclude 'spec/**/*'
35
- gemspec.add_dependency('rails', '>= 2.3.0')
36
- end
37
- rescue LoadError
38
- puts "Jeweler not available. Install it with: sudo gem install jeweler"
39
- end
data/jelly.gemspec CHANGED
@@ -4,8 +4,8 @@
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
- s.name = %q{jelly}
8
- s.version = "0.9.0"
7
+ s.name = %q{honkster-jelly}
8
+ s.version = "0.9.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Pivotal Labs, Inc"]
@@ -15,72 +15,21 @@ Gem::Specification.new do |s|
15
15
  s.extra_rdoc_files = [
16
16
  "README.markdown"
17
17
  ]
18
- s.files = [
19
- ".bundle/config",
20
- ".rvmrc",
21
- "Gemfile",
22
- "Gemfile.lock",
23
- "MIT-LICENSE",
24
- "README.markdown",
25
- "Rakefile",
26
- "VERSION.yml",
27
- "generators/jelly/USAGE",
28
- "generators/jelly/jelly_generator.rb",
29
- "generators/jelly/templates/javascripts/ajax_with_jelly.js",
30
- "generators/jelly/templates/javascripts/jelly.js",
31
- "generators/jelly/templates/javascripts/jquery/jquery-1.3.2.js",
32
- "install.rb",
33
- "jelly.gemspec",
34
- "lib/jelly.rb",
35
- "lib/jelly/common.rb",
36
- "lib/jelly/jelly_controller.rb",
37
- "lib/jelly/jelly_helper.rb",
38
- "spec/rails_root/.gitignore",
39
- "spec/rails_root/lib/tasks/.gitkeep",
40
- "spec/rails_root/public/stylesheets/.gitkeep",
41
- "spec/rails_root/vendor/plugins/.gitkeep",
42
- "tasks/jelly_tasks.rake",
43
- "uninstall.rb"
44
- ]
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
45
20
  s.homepage = %q{http://github.com/pivotal/jelly}
46
21
  s.require_paths = ["lib"]
47
22
  s.rubygems_version = %q{1.5.2}
48
23
  s.summary = %q{a sweet unobtrusive javascript framework for jQuery and Rails}
49
24
 
50
- if s.respond_to? :specification_version then
51
- s.specification_version = 3
52
-
53
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
54
- s.add_runtime_dependency(%q<capybara>, ["= 0.4.1.2"])
55
- s.add_runtime_dependency(%q<jeweler>, ["= 1.6.2"])
56
- s.add_runtime_dependency(%q<rails>, ["= 3.0.8"])
57
- s.add_runtime_dependency(%q<rake>, ["= 0.9.2"])
58
- s.add_runtime_dependency(%q<rr>, ["= 1.0.2"])
59
- s.add_runtime_dependency(%q<rspec>, ["= 2.6.0"])
60
- s.add_runtime_dependency(%q<rspec-rails>, ["= 2.6.1"])
61
- s.add_runtime_dependency(%q<sqlite3>, ["= 1.3.3"])
62
- s.add_runtime_dependency(%q<rails>, [">= 2.3.0"])
63
- else
64
- s.add_dependency(%q<capybara>, ["= 0.4.1.2"])
65
- s.add_dependency(%q<jeweler>, ["= 1.6.2"])
66
- s.add_dependency(%q<rails>, ["= 3.0.8"])
67
- s.add_dependency(%q<rake>, ["= 0.9.2"])
68
- s.add_dependency(%q<rr>, ["= 1.0.2"])
69
- s.add_dependency(%q<rspec>, ["= 2.6.0"])
70
- s.add_dependency(%q<rspec-rails>, ["= 2.6.1"])
71
- s.add_dependency(%q<sqlite3>, ["= 1.3.3"])
72
- s.add_dependency(%q<rails>, [">= 2.3.0"])
73
- end
74
- else
75
- s.add_dependency(%q<capybara>, ["= 0.4.1.2"])
76
- s.add_dependency(%q<jeweler>, ["= 1.6.2"])
77
- s.add_dependency(%q<rails>, ["= 3.0.8"])
78
- s.add_dependency(%q<rake>, ["= 0.9.2"])
79
- s.add_dependency(%q<rr>, ["= 1.0.2"])
80
- s.add_dependency(%q<rspec>, ["= 2.6.0"])
81
- s.add_dependency(%q<rspec-rails>, ["= 2.6.1"])
82
- s.add_dependency(%q<sqlite3>, ["= 1.3.3"])
83
- s.add_dependency(%q<rails>, [">= 2.3.0"])
84
- end
25
+ s.add_runtime_dependency("capybara", ["= 0.4.1.2"])
26
+ s.add_runtime_dependency("jeweler", ["= 1.6.2"])
27
+ s.add_runtime_dependency("rails", ["= 3.0.8"])
28
+ s.add_runtime_dependency("rake", ["= 0.9.2"])
29
+ s.add_runtime_dependency("rr", ["= 1.0.2"])
30
+ s.add_runtime_dependency("rspec", ["= 2.6.0"])
31
+ s.add_runtime_dependency("rspec-rails", ["= 2.6.1"])
32
+ s.add_runtime_dependency("sqlite3", ["= 1.3.3"])
33
+ s.add_runtime_dependency("rails", [">= 2.3.0"])
85
34
  end
86
35
 
@@ -27,7 +27,7 @@ module JellyHelper
27
27
  def attach_javascript_component_javascript_tag(*components)
28
28
  components = [components].flatten
29
29
  javascript_tag <<-JS
30
- $(document).ready(function() {
30
+ jQuery(document).ready(function() {
31
31
  Jelly.attach.apply(Jelly, #{components.to_json});
32
32
  });
33
33
  JS
File without changes
@@ -0,0 +1,129 @@
1
+ jasmine.TrivialReporter = function(doc) {
2
+ this.document = doc || document;
3
+ this.suiteDivs = {};
4
+ };
5
+
6
+ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
7
+ var el = document.createElement(type);
8
+
9
+ for (var i = 2; i < arguments.length; i++) {
10
+ var child = arguments[i];
11
+
12
+ if (typeof child === 'string') {
13
+ el.appendChild(document.createTextNode(child));
14
+ } else {
15
+ if (child) { el.appendChild(child); }
16
+ }
17
+ }
18
+
19
+ for (var attr in attrs) {
20
+ el[attr] = attrs[attr];
21
+ }
22
+
23
+ return el;
24
+ };
25
+
26
+ jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
27
+ var suites = runner.suites();
28
+
29
+ this.runnerDiv = this.createDom('div', { className: 'runner running' },
30
+ this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
31
+ this.runnerMessageSpan = this.createDom('span', {}, "Running..."));
32
+ this.document.body.appendChild(this.runnerDiv);
33
+
34
+ for (var i = 0; i < suites.length; i++) {
35
+ var suite = suites[i];
36
+ var suiteDiv = this.createDom('div', { className: 'suite' },
37
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
38
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
39
+ this.suiteDivs[suite.getFullName()] = suiteDiv;
40
+ var parentDiv = this.document.body;
41
+ if (suite.parentSuite) {
42
+ parentDiv = this.suiteDivs[suite.parentSuite.getFullName()];
43
+ }
44
+ parentDiv.appendChild(suiteDiv);
45
+ }
46
+
47
+ this.startedAt = new Date();
48
+ };
49
+
50
+ jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
51
+ var results = runner.results();
52
+ var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
53
+ this.runnerDiv.setAttribute("class", className);
54
+ //do it twice for IE
55
+ this.runnerDiv.setAttribute("className", className);
56
+ var specs = runner.specs();
57
+ var specCount = 0;
58
+ for (var i = 0; i < specs.length; i++) {
59
+ if (this.specFilter(specs[i])) {
60
+ specCount++;
61
+ }
62
+ }
63
+ var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
64
+ message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
65
+ this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
66
+ };
67
+
68
+ jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
69
+ var results = suite.results();
70
+ var status = results.passed() ? 'passed' : 'failed';
71
+ if (results.totalCount == 0) { // todo: change this to check results.skipped
72
+ status = 'skipped';
73
+ }
74
+ this.suiteDivs[suite.getFullName()].className += " " + status;
75
+ };
76
+
77
+ jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
78
+ var results = spec.results();
79
+ var status = results.passed() ? 'passed' : 'failed';
80
+ if (results.skipped) {
81
+ status = 'skipped';
82
+ }
83
+ var specDiv = this.createDom('div', { className: 'spec ' + status },
84
+ this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
85
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, spec.getFullName()));
86
+
87
+
88
+ var resultItems = results.getItems();
89
+ for (var i = 0; i < resultItems.length; i++) {
90
+ var result = resultItems[i];
91
+ if (result.passed && !result.passed()) {
92
+ var resultMessageDiv = this.createDom('div', {className: 'resultMessage fail'});
93
+ resultMessageDiv.innerHTML = result.message; // todo: lame; mend
94
+ specDiv.appendChild(resultMessageDiv);
95
+ specDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
96
+ }
97
+ }
98
+ this.suiteDivs[spec.suite.getFullName()].appendChild(specDiv);
99
+ };
100
+
101
+ jasmine.TrivialReporter.prototype.log = function() {
102
+ console.log.apply(console, arguments);
103
+ };
104
+
105
+ jasmine.TrivialReporter.prototype.getLocation = function() {
106
+ return this.document.location;
107
+ };
108
+
109
+ jasmine.TrivialReporter.prototype.specFilter = function(spec) {
110
+ var paramMap = {};
111
+ var params = this.getLocation().search.substring(1).split('&');
112
+ for (var i = 0; i < params.length; i++) {
113
+ var p = params[i].split('=');
114
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
115
+ }
116
+
117
+ if (!paramMap["spec"]) return true;
118
+ return spec.getFullName().indexOf(paramMap["spec"]) == 0;
119
+ };
120
+
121
+ //protect against console.log incidents
122
+ if (!("console" in window) || !("firebug" in console)) {
123
+ var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
124
+ window.console = {};
125
+ for (var i = 0, len = names.length; i < len; ++i) {
126
+ window.console[names[i]] = function() {
127
+ };
128
+ }
129
+ }
@@ -0,0 +1,2149 @@
1
+ /**
2
+ * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
3
+ *
4
+ * @namespace
5
+ */
6
+ var jasmine = {};
7
+
8
+ /**
9
+ * @private
10
+ */
11
+ jasmine.unimplementedMethod_ = function() {
12
+ throw new Error("unimplemented method");
13
+ };
14
+
15
+ /**
16
+ * Large or small values here may result in slow test running & "Too much recursion" errors
17
+ *
18
+ */
19
+ jasmine.UPDATE_INTERVAL = 250;
20
+
21
+ /**
22
+ * Allows for bound functions to be comapred. Internal use only.
23
+ *
24
+ * @ignore
25
+ * @private
26
+ * @param base {Object} bound 'this' for the function
27
+ * @param name {Function} function to find
28
+ */
29
+ jasmine.bindOriginal_ = function(base, name) {
30
+ var original = base[name];
31
+ return function() {
32
+ if (original.apply) {
33
+ return original.apply(base, arguments);
34
+ } else {
35
+ //IE support
36
+ if (base == window) {
37
+ return window[name].apply(window, arguments);
38
+ }
39
+ }
40
+ };
41
+ };
42
+
43
+ jasmine.setTimeout = jasmine.bindOriginal_(window, 'setTimeout');
44
+ jasmine.clearTimeout = jasmine.bindOriginal_(window, 'clearTimeout');
45
+ jasmine.setInterval = jasmine.bindOriginal_(window, 'setInterval');
46
+ jasmine.clearInterval = jasmine.bindOriginal_(window, 'clearInterval');
47
+
48
+ jasmine.MessageResult = function(text) {
49
+ this.type = 'MessageResult';
50
+ this.text = text;
51
+ this.trace = new Error(); // todo: test better
52
+ };
53
+
54
+ jasmine.ExpectationResult = function(passed, message, details) {
55
+ this.type = 'ExpectationResult';
56
+ this.passed_ = passed;
57
+ this.message = message;
58
+ this.details = details;
59
+ this.trace = new Error(message); // todo: test better
60
+ };
61
+
62
+ jasmine.ExpectationResult.prototype.passed = function () {
63
+ return this.passed_;
64
+ };
65
+
66
+ /**
67
+ * Getter for the Jasmine environment. Ensures one gets created
68
+ */
69
+ jasmine.getEnv = function() {
70
+ return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
71
+ };
72
+
73
+ /**
74
+ * @ignore
75
+ * @private
76
+ * @param value
77
+ * @returns {Boolean}
78
+ */
79
+ jasmine.isArray_ = function(value) {
80
+ return value &&
81
+ typeof value === 'object' &&
82
+ typeof value.length === 'number' &&
83
+ typeof value.splice === 'function' &&
84
+ !(value.propertyIsEnumerable('length'));
85
+ };
86
+
87
+ /**
88
+ * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
89
+ *
90
+ * @param value {Object} an object to be outputted
91
+ * @returns {String}
92
+ */
93
+ jasmine.pp = function(value) {
94
+ var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
95
+ stringPrettyPrinter.format(value);
96
+ return stringPrettyPrinter.string;
97
+ };
98
+
99
+ /**
100
+ * Returns true if the object is a DOM Node.
101
+ *
102
+ * @param {Object} obj object to check
103
+ * @returns {Boolean}
104
+ */
105
+ jasmine.isDomNode = function(obj) {
106
+ return obj['nodeType'] > 0;
107
+ };
108
+
109
+ /**
110
+ * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
111
+ *
112
+ * @example
113
+ * // don't care about which function is passed in, as long as it's a function
114
+ * expect(mySpy).wasCalledWith(jasmine.any(Function));
115
+ *
116
+ * @param {Class} clazz
117
+ * @returns matchable object of the type clazz
118
+ */
119
+ jasmine.any = function(clazz) {
120
+ return new jasmine.Matchers.Any(clazz);
121
+ };
122
+
123
+ /**
124
+ * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
125
+ *
126
+ * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
127
+ * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
128
+ *
129
+ * A Spy has the following mehtod: wasCalled, callCount, mostRecentCall, and argsForCall (see docs)
130
+ * Spies are torn down at the end of every spec.
131
+ *
132
+ * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
133
+ *
134
+ * @example
135
+ * // a stub
136
+ * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
137
+ *
138
+ * // spy example
139
+ * var foo = {
140
+ * not: function(bool) { return !bool; }
141
+ * }
142
+ *
143
+ * // actual foo.not will not be called, execution stops
144
+ * spyOn(foo, 'not');
145
+
146
+ // foo.not spied upon, execution will continue to implementation
147
+ * spyOn(foo, 'not').andCallThrough();
148
+ *
149
+ * // fake example
150
+ * var foo = {
151
+ * not: function(bool) { return !bool; }
152
+ * }
153
+ *
154
+ * // foo.not(val) will return val
155
+ * spyOn(foo, 'not').andCallFake(function(value) {return value;});
156
+ *
157
+ * // mock example
158
+ * foo.not(7 == 7);
159
+ * expect(foo.not).wasCalled();
160
+ * expect(foo.not).wasCalledWith(true);
161
+ *
162
+ * @constructor
163
+ * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
164
+ * @param {String} name
165
+ */
166
+ jasmine.Spy = function(name) {
167
+ /**
168
+ * The name of the spy, if provided.
169
+ */
170
+ this.identity = name || 'unknown';
171
+ /**
172
+ * Is this Object a spy?
173
+ */
174
+ this.isSpy = true;
175
+ /**
176
+ * The acutal function this spy stubs.
177
+ */
178
+ this.plan = function() {
179
+ };
180
+ /**
181
+ * Tracking of the most recent call to the spy.
182
+ * @example
183
+ * var mySpy = jasmine.createSpy('foo');
184
+ * mySpy(1, 2);
185
+ * mySpy.mostRecentCall.args = [1, 2];
186
+ */
187
+ this.mostRecentCall = {};
188
+
189
+ /**
190
+ * Holds arguments for each call to the spy, indexed by call count
191
+ * @example
192
+ * var mySpy = jasmine.createSpy('foo');
193
+ * mySpy(1, 2);
194
+ * mySpy(7, 8);
195
+ * mySpy.mostRecentCall.args = [7, 8];
196
+ * mySpy.argsForCall[0] = [1, 2];
197
+ * mySpy.argsForCall[1] = [7, 8];
198
+ */
199
+ this.argsForCall = [];
200
+ this.calls = [];
201
+ };
202
+
203
+ /**
204
+ * Tells a spy to call through to the actual implemenatation.
205
+ *
206
+ * @example
207
+ * var foo = {
208
+ * bar: function() { // do some stuff }
209
+ * }
210
+ *
211
+ * // defining a spy on an existing property: foo.bar
212
+ * spyOn(foo, 'bar').andCallThrough();
213
+ */
214
+ jasmine.Spy.prototype.andCallThrough = function() {
215
+ this.plan = this.originalValue;
216
+ return this;
217
+ };
218
+
219
+ /**
220
+ * For setting the return value of a spy.
221
+ *
222
+ * @example
223
+ * // defining a spy from scratch: foo() returns 'baz'
224
+ * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
225
+ *
226
+ * // defining a spy on an existing property: foo.bar() returns 'baz'
227
+ * spyOn(foo, 'bar').andReturn('baz');
228
+ *
229
+ * @param {Object} value
230
+ */
231
+ jasmine.Spy.prototype.andReturn = function(value) {
232
+ this.plan = function() {
233
+ return value;
234
+ };
235
+ return this;
236
+ };
237
+
238
+ /**
239
+ * For throwing an exception when a spy is called.
240
+ *
241
+ * @example
242
+ * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
243
+ * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
244
+ *
245
+ * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
246
+ * spyOn(foo, 'bar').andThrow('baz');
247
+ *
248
+ * @param {String} exceptionMsg
249
+ */
250
+ jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
251
+ this.plan = function() {
252
+ throw exceptionMsg;
253
+ };
254
+ return this;
255
+ };
256
+
257
+ /**
258
+ * Calls an alternate implementation when a spy is called.
259
+ *
260
+ * @example
261
+ * var baz = function() {
262
+ * // do some stuff, return something
263
+ * }
264
+ * // defining a spy from scratch: foo() calls the function baz
265
+ * var foo = jasmine.createSpy('spy on foo').andCall(baz);
266
+ *
267
+ * // defining a spy on an existing property: foo.bar() calls an anonymnous function
268
+ * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
269
+ *
270
+ * @param {Function} fakeFunc
271
+ */
272
+ jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
273
+ this.plan = fakeFunc;
274
+ return this;
275
+ };
276
+
277
+ /**
278
+ * Resets all of a spy's the tracking variables so that it can be used again.
279
+ *
280
+ * @example
281
+ * spyOn(foo, 'bar');
282
+ *
283
+ * foo.bar();
284
+ *
285
+ * expect(foo.bar.callCount).toEqual(1);
286
+ *
287
+ * foo.bar.reset();
288
+ *
289
+ * expect(foo.bar.callCount).toEqual(0);
290
+ */
291
+ jasmine.Spy.prototype.reset = function() {
292
+ this.wasCalled = false;
293
+ this.callCount = 0;
294
+ this.argsForCall = [];
295
+ this.calls = [];
296
+ this.mostRecentCall = {};
297
+ };
298
+
299
+ jasmine.createSpy = function(name) {
300
+
301
+ var spyObj = function() {
302
+ spyObj.wasCalled = true;
303
+ spyObj.callCount++;
304
+ var args = jasmine.util.argsToArray(arguments);
305
+ spyObj.mostRecentCall.object = this;
306
+ spyObj.mostRecentCall.args = args;
307
+ spyObj.argsForCall.push(args);
308
+ spyObj.calls.push({object: this, args: args});
309
+ return spyObj.plan.apply(this, arguments);
310
+ };
311
+
312
+ var spy = new jasmine.Spy(name);
313
+
314
+ for (var prop in spy) {
315
+ spyObj[prop] = spy[prop];
316
+ }
317
+
318
+ spyObj.reset();
319
+
320
+ return spyObj;
321
+ };
322
+
323
+ /**
324
+ * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
325
+ * large in one call.
326
+ *
327
+ * @param {String} baseName name of spy class
328
+ * @param {Array} methodNames array of names of methods to make spies
329
+ */
330
+ jasmine.createSpyObj = function(baseName, methodNames) {
331
+ var obj = {};
332
+ for (var i = 0; i < methodNames.length; i++) {
333
+ obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
334
+ }
335
+ return obj;
336
+ };
337
+
338
+ jasmine.log = function(message) {
339
+ jasmine.getEnv().currentSpec.log(message);
340
+ };
341
+
342
+ /**
343
+ * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
344
+ *
345
+ * @example
346
+ * // spy example
347
+ * var foo = {
348
+ * not: function(bool) { return !bool; }
349
+ * }
350
+ * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
351
+ *
352
+ * @see jasmine.createSpy
353
+ * @param obj
354
+ * @param methodName
355
+ * @returns a Jasmine spy that can be chained with all spy methods
356
+ */
357
+ var spyOn = function(obj, methodName) {
358
+ return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
359
+ };
360
+
361
+ /**
362
+ * Creates a Jasmine spec that will be added to the current suite.
363
+ *
364
+ * // TODO: pending tests
365
+ *
366
+ * @example
367
+ * it('should be true', function() {
368
+ * expect(true).toEqual(true);
369
+ * });
370
+ *
371
+ * @param {String} desc description of this specification
372
+ * @param {Function} func defines the preconditions and expectations of the spec
373
+ */
374
+ var it = function(desc, func) {
375
+ return jasmine.getEnv().it(desc, func);
376
+ };
377
+
378
+ /**
379
+ * Creates a <em>disabled</em> Jasmine spec.
380
+ *
381
+ * A convenience method that allows existing specs to be disabled temporarily during development.
382
+ *
383
+ * @param {String} desc description of this specification
384
+ * @param {Function} func defines the preconditions and expectations of the spec
385
+ */
386
+ var xit = function(desc, func) {
387
+ return jasmine.getEnv().xit(desc, func);
388
+ };
389
+
390
+ /**
391
+ * Starts a chain for a Jasmine expectation.
392
+ *
393
+ * It is passed an Object that is the actual value and should chain to one of the many
394
+ * jasmine.Matchers functions.
395
+ *
396
+ * @param {Object} actual Actual value to test against and expected value
397
+ */
398
+ var expect = function(actual) {
399
+ return jasmine.getEnv().currentSpec.expect(actual);
400
+ };
401
+
402
+ /**
403
+ * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
404
+ *
405
+ * @param {Function} func Function that defines part of a jasmine spec.
406
+ */
407
+ var runs = function(func) {
408
+ jasmine.getEnv().currentSpec.runs(func);
409
+ };
410
+
411
+ /**
412
+ * Waits for a timeout before moving to the next runs()-defined block.
413
+ * @param {Number} timeout
414
+ */
415
+ var waits = function(timeout) {
416
+ jasmine.getEnv().currentSpec.waits(timeout);
417
+ };
418
+
419
+ /**
420
+ * Waits for the latchFunction to return true before proceeding to the next runs()-defined block.
421
+ *
422
+ * @param {Number} timeout
423
+ * @param {Function} latchFunction
424
+ * @param {String} message
425
+ */
426
+ var waitsFor = function(timeout, latchFunction, message) {
427
+ jasmine.getEnv().currentSpec.waitsFor(timeout, latchFunction, message);
428
+ };
429
+
430
+ /**
431
+ * A function that is called before each spec in a suite.
432
+ *
433
+ * Used for spec setup, including validating assumptions.
434
+ *
435
+ * @param {Function} beforeEachFunction
436
+ */
437
+ var beforeEach = function(beforeEachFunction) {
438
+ jasmine.getEnv().beforeEach(beforeEachFunction);
439
+ };
440
+
441
+ /**
442
+ * A function that is called after each spec in a suite.
443
+ *
444
+ * Used for restoring any state that is hijacked during spec execution.
445
+ *
446
+ * @param {Function} afterEachFunction
447
+ */
448
+ var afterEach = function(afterEachFunction) {
449
+ jasmine.getEnv().afterEach(afterEachFunction);
450
+ };
451
+
452
+ /**
453
+ * Defines a suite of specifications.
454
+ *
455
+ * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
456
+ * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
457
+ * of setup in some tests.
458
+ *
459
+ * @example
460
+ * // TODO: a simple suite
461
+ *
462
+ * // TODO: a simple suite with a nested describe block
463
+ *
464
+ * @param {String} description A string, usually the class under test.
465
+ * @param {Function} specDefinitions function that defines several specs.
466
+ */
467
+ var describe = function(description, specDefinitions) {
468
+ return jasmine.getEnv().describe(description, specDefinitions);
469
+ };
470
+
471
+ /**
472
+ * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
473
+ *
474
+ * @param {String} description A string, usually the class under test.
475
+ * @param {Function} specDefinitions function that defines several specs.
476
+ */
477
+ var xdescribe = function(description, specDefinitions) {
478
+ return jasmine.getEnv().xdescribe(description, specDefinitions);
479
+ };
480
+
481
+
482
+ jasmine.XmlHttpRequest = XMLHttpRequest;
483
+
484
+ // Provide the XMLHttpRequest class for IE 5.x-6.x:
485
+ if (typeof XMLHttpRequest == "undefined") jasmine.XmlHttpRequest = function() {
486
+ try {
487
+ return new ActiveXObject("Msxml2.XMLHTTP.6.0");
488
+ } catch(e) {
489
+ }
490
+ try {
491
+ return new ActiveXObject("Msxml2.XMLHTTP.3.0");
492
+ } catch(e) {
493
+ }
494
+ try {
495
+ return new ActiveXObject("Msxml2.XMLHTTP");
496
+ } catch(e) {
497
+ }
498
+ try {
499
+ return new ActiveXObject("Microsoft.XMLHTTP");
500
+ } catch(e) {
501
+ }
502
+ throw new Error("This browser does not support XMLHttpRequest.");
503
+ };
504
+
505
+ /**
506
+ * Adds suite files to an HTML document so that they are executed, thus adding them to the current
507
+ * Jasmine environment.
508
+ *
509
+ * @param {String} url path to the file to include
510
+ * @param {Boolean} opt_global
511
+ */
512
+ jasmine.include = function(url, opt_global) {
513
+ if (opt_global) {
514
+ document.write('<script type="text/javascript" src="' + url + '"></' + 'script>');
515
+ } else {
516
+ var xhr;
517
+ try {
518
+ xhr = new jasmine.XmlHttpRequest();
519
+ xhr.open("GET", url, false);
520
+ xhr.send(null);
521
+ } catch(e) {
522
+ throw new Error("couldn't fetch " + url + ": " + e);
523
+ }
524
+
525
+ return eval(xhr.responseText);
526
+ }
527
+ };
528
+
529
+ jasmine.version_= {
530
+ "major": 0,
531
+ "minor": 10,
532
+ "build": 0,
533
+ "revision": 1256707024
534
+ };
535
+ /**
536
+ * @namespace
537
+ */
538
+ jasmine.util = {};
539
+
540
+ /**
541
+ * Declare that a child class inherite it's prototype from the parent class.
542
+ *
543
+ * @private
544
+ * @param {Function} childClass
545
+ * @param {Function} parentClass
546
+ */
547
+ jasmine.util.inherit = function(childClass, parentClass) {
548
+ var subclass = function() {
549
+ };
550
+ subclass.prototype = parentClass.prototype;
551
+ childClass.prototype = new subclass;
552
+ };
553
+
554
+ jasmine.util.formatException = function(e) {
555
+ var lineNumber;
556
+ if (e.line) {
557
+ lineNumber = e.line;
558
+ }
559
+ else if (e.lineNumber) {
560
+ lineNumber = e.lineNumber;
561
+ }
562
+
563
+ var file;
564
+
565
+ if (e.sourceURL) {
566
+ file = e.sourceURL;
567
+ }
568
+ else if (e.fileName) {
569
+ file = e.fileName;
570
+ }
571
+
572
+ var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
573
+
574
+ if (file && lineNumber) {
575
+ message += ' in ' + file + ' (line ' + lineNumber + ')';
576
+ }
577
+
578
+ return message;
579
+ };
580
+
581
+ jasmine.util.htmlEscape = function(str) {
582
+ if (!str) return str;
583
+ return str.replace(/&/g, '&amp;')
584
+ .replace(/</g, '&lt;')
585
+ .replace(/>/g, '&gt;');
586
+ };
587
+
588
+ jasmine.util.argsToArray = function(args) {
589
+ var arrayOfArgs = [];
590
+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
591
+ return arrayOfArgs;
592
+ };
593
+
594
+ /**
595
+ * Environment for Jasmine
596
+ *
597
+ * @constructor
598
+ */
599
+ jasmine.Env = function() {
600
+ this.currentSpec = null;
601
+ this.currentSuite = null;
602
+ this.currentRunner_ = new jasmine.Runner(this);
603
+
604
+ this.reporter = new jasmine.MultiReporter();
605
+
606
+ this.updateInterval = jasmine.UPDATE_INTERVAL
607
+ this.lastUpdate = 0;
608
+ this.specFilter = function() {
609
+ return true;
610
+ };
611
+
612
+ this.nextSpecId_ = 0;
613
+ this.nextSuiteId_ = 0;
614
+ this.equalityTesters_ = [];
615
+ };
616
+
617
+
618
+ jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
619
+ jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
620
+ jasmine.Env.prototype.setInterval = jasmine.setInterval;
621
+ jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
622
+
623
+ /**
624
+ * @returns an object containing jasmine version build info, if set.
625
+ */
626
+ jasmine.Env.prototype.version = function () {
627
+ if (jasmine.version_) {
628
+ return jasmine.version_;
629
+ } else {
630
+ throw new Error('Version not set');
631
+ }
632
+ };
633
+
634
+ /**
635
+ * @returns a sequential integer starting at 0
636
+ */
637
+ jasmine.Env.prototype.nextSpecId = function () {
638
+ return this.nextSpecId_++;
639
+ };
640
+
641
+ /**
642
+ * @returns a sequential integer starting at 0
643
+ */
644
+ jasmine.Env.prototype.nextSuiteId = function () {
645
+ return this.nextSuiteId_++;
646
+ };
647
+
648
+ /**
649
+ * Register a reporter to receive status updates from Jasmine.
650
+ * @param {jasmine.Reporter} reporter An object which will receive status updates.
651
+ */
652
+ jasmine.Env.prototype.addReporter = function(reporter) {
653
+ this.reporter.addReporter(reporter);
654
+ };
655
+
656
+ jasmine.Env.prototype.execute = function() {
657
+ this.currentRunner_.execute();
658
+ };
659
+
660
+ jasmine.Env.prototype.describe = function(description, specDefinitions) {
661
+ var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
662
+
663
+ var parentSuite = this.currentSuite;
664
+ if (parentSuite) {
665
+ parentSuite.add(suite);
666
+ } else {
667
+ this.currentRunner_.add(suite);
668
+ }
669
+
670
+ this.currentSuite = suite;
671
+
672
+ specDefinitions.call(suite);
673
+
674
+ this.currentSuite = parentSuite;
675
+
676
+ return suite;
677
+ };
678
+
679
+ jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
680
+ if (this.currentSuite) {
681
+ this.currentSuite.beforeEach(beforeEachFunction);
682
+ } else {
683
+ this.currentRunner_.beforeEach(beforeEachFunction);
684
+ }
685
+ };
686
+
687
+ jasmine.Env.prototype.currentRunner = function () {
688
+ return this.currentRunner_;
689
+ };
690
+
691
+ jasmine.Env.prototype.afterEach = function(afterEachFunction) {
692
+ if (this.currentSuite) {
693
+ this.currentSuite.afterEach(afterEachFunction);
694
+ } else {
695
+ this.currentRunner_.afterEach(afterEachFunction);
696
+ }
697
+
698
+ };
699
+
700
+ jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
701
+ return {
702
+ execute: function() {
703
+ }
704
+ };
705
+ };
706
+
707
+ jasmine.Env.prototype.it = function(description, func) {
708
+ var spec = new jasmine.Spec(this, this.currentSuite, description);
709
+ this.currentSuite.add(spec);
710
+ this.currentSpec = spec;
711
+
712
+ if (func) {
713
+ spec.runs(func);
714
+ }
715
+
716
+ return spec;
717
+ };
718
+
719
+ jasmine.Env.prototype.xit = function(desc, func) {
720
+ return {
721
+ id: this.nextSpecId(),
722
+ runs: function() {
723
+ }
724
+ };
725
+ };
726
+
727
+ jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
728
+ if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
729
+ return true;
730
+ }
731
+
732
+ a.__Jasmine_been_here_before__ = b;
733
+ b.__Jasmine_been_here_before__ = a;
734
+
735
+ var hasKey = function(obj, keyName) {
736
+ return obj != null && obj[keyName] !== undefined;
737
+ };
738
+
739
+ for (var property in b) {
740
+ if (!hasKey(a, property) && hasKey(b, property)) {
741
+ mismatchKeys.push("expected has key '" + property + "', but missing from <b>actual</b>.");
742
+ }
743
+ }
744
+ for (property in a) {
745
+ if (!hasKey(b, property) && hasKey(a, property)) {
746
+ mismatchKeys.push("<b>expected</b> missing key '" + property + "', but present in actual.");
747
+ }
748
+ }
749
+ for (property in b) {
750
+ if (property == '__Jasmine_been_here_before__') continue;
751
+ if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
752
+ mismatchValues.push("'" + property + "' was<br /><br />'" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "'<br /><br />in expected, but was<br /><br />'" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "'<br /><br />in actual.<br />");
753
+ }
754
+ }
755
+
756
+ if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
757
+ mismatchValues.push("arrays were not the same length");
758
+ }
759
+
760
+ delete a.__Jasmine_been_here_before__;
761
+ delete b.__Jasmine_been_here_before__;
762
+ return (mismatchKeys.length == 0 && mismatchValues.length == 0);
763
+ };
764
+
765
+ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
766
+ mismatchKeys = mismatchKeys || [];
767
+ mismatchValues = mismatchValues || [];
768
+
769
+ if (a === b) return true;
770
+
771
+ if (a === undefined || a === null || b === undefined || b === null) {
772
+ return (a == undefined && b == undefined);
773
+ }
774
+
775
+ if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
776
+ return a === b;
777
+ }
778
+
779
+ if (a instanceof Date && b instanceof Date) {
780
+ return a.getTime() == b.getTime();
781
+ }
782
+
783
+ if (a instanceof jasmine.Matchers.Any) {
784
+ return a.matches(b);
785
+ }
786
+
787
+ if (b instanceof jasmine.Matchers.Any) {
788
+ return b.matches(a);
789
+ }
790
+
791
+ if (typeof a === "object" && typeof b === "object") {
792
+ return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
793
+ }
794
+
795
+ for (var i = 0; i < this.equalityTesters_.length; i++) {
796
+ var equalityTester = this.equalityTesters_[i];
797
+ var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
798
+ if (result !== undefined) return result;
799
+ }
800
+
801
+ //Straight check
802
+ return (a === b);
803
+ };
804
+
805
+ jasmine.Env.prototype.contains_ = function(haystack, needle) {
806
+ if (jasmine.isArray_(haystack)) {
807
+ for (var i = 0; i < haystack.length; i++) {
808
+ if (this.equals_(haystack[i], needle)) return true;
809
+ }
810
+ return false;
811
+ }
812
+ return haystack.indexOf(needle) >= 0;
813
+ };
814
+
815
+ jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
816
+ this.equalityTesters_.push(equalityTester);
817
+ };
818
+ /** No-op base class for Jasmine reporters.
819
+ *
820
+ * @constructor
821
+ */
822
+ jasmine.Reporter = function() {
823
+ };
824
+
825
+ //noinspection JSUnusedLocalSymbols
826
+ jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
827
+ };
828
+
829
+ //noinspection JSUnusedLocalSymbols
830
+ jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
831
+ };
832
+
833
+ //noinspection JSUnusedLocalSymbols
834
+ jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
835
+ };
836
+
837
+ //noinspection JSUnusedLocalSymbols
838
+ jasmine.Reporter.prototype.reportSpecResults = function(spec) {
839
+ };
840
+
841
+ //noinspection JSUnusedLocalSymbols
842
+ jasmine.Reporter.prototype.log = function(str) {
843
+ };
844
+
845
+ /**
846
+ * Blocks are functions with executable code that make up a spec.
847
+ *
848
+ * @constructor
849
+ * @param {jasmine.Env} env
850
+ * @param {Function} func
851
+ * @param {jasmine.Spec} spec
852
+ */
853
+ jasmine.Block = function(env, func, spec) {
854
+ this.env = env;
855
+ this.func = func;
856
+ this.spec = spec;
857
+ };
858
+
859
+ jasmine.Block.prototype.execute = function(onComplete) {
860
+ try {
861
+ this.func.apply(this.spec);
862
+ } catch (e) {
863
+ this.spec.fail(e);
864
+ }
865
+ onComplete();
866
+ };
867
+ /** JavaScript API reporter.
868
+ *
869
+ * @constructor
870
+ */
871
+ jasmine.JsApiReporter = function() {
872
+ this.started = false;
873
+ this.finished = false;
874
+ this.suites_ = [];
875
+ this.results_ = {};
876
+ };
877
+
878
+ jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
879
+ this.started = true;
880
+ var suites = runner.suites();
881
+ for (var i = 0; i < suites.length; i++) {
882
+ var suite = suites[i];
883
+ this.suites_.push(this.summarize_(suite));
884
+ }
885
+ };
886
+
887
+ jasmine.JsApiReporter.prototype.suites = function() {
888
+ return this.suites_;
889
+ };
890
+
891
+ jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
892
+ var isSuite = suiteOrSpec instanceof jasmine.Suite
893
+ var summary = {
894
+ id: suiteOrSpec.id,
895
+ name: suiteOrSpec.description,
896
+ type: isSuite ? 'suite' : 'spec',
897
+ children: []
898
+ };
899
+ if (isSuite) {
900
+ var specs = suiteOrSpec.specs();
901
+ for (var i = 0; i < specs.length; i++) {
902
+ summary.children.push(this.summarize_(specs[i]));
903
+ }
904
+ }
905
+ return summary;
906
+ };
907
+
908
+ jasmine.JsApiReporter.prototype.results = function() {
909
+ return this.results_;
910
+ };
911
+
912
+ jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
913
+ return this.results_[specId];
914
+ };
915
+
916
+ //noinspection JSUnusedLocalSymbols
917
+ jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
918
+ this.finished = true;
919
+ };
920
+
921
+ //noinspection JSUnusedLocalSymbols
922
+ jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
923
+ };
924
+
925
+ //noinspection JSUnusedLocalSymbols
926
+ jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
927
+ this.results_[spec.id] = {
928
+ messages: spec.results().getItems(),
929
+ result: spec.results().failedCount > 0 ? "failed" : "passed"
930
+ };
931
+ };
932
+
933
+ //noinspection JSUnusedLocalSymbols
934
+ jasmine.JsApiReporter.prototype.log = function(str) {
935
+ };
936
+
937
+ jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
938
+ var results = {};
939
+ for (var i = 0; i < specIds.length; i++) {
940
+ var specId = specIds[i];
941
+ results[specId] = this.summarizeResult_(this.results_[specId]);
942
+ }
943
+ return results;
944
+ };
945
+
946
+ jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
947
+ var summaryMessages = [];
948
+ for (var messageIndex in result.messages) {
949
+ var resultMessage = result.messages[messageIndex];
950
+ summaryMessages.push({
951
+ text: resultMessage.text,
952
+ passed: resultMessage.passed ? resultMessage.passed() : true,
953
+ type: resultMessage.type,
954
+ message: resultMessage.message,
955
+ trace: {
956
+ stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : undefined
957
+ }
958
+ });
959
+ };
960
+
961
+ var summaryResult = {
962
+ result : result.result,
963
+ messages : summaryMessages
964
+ };
965
+
966
+ return summaryResult;
967
+ };
968
+
969
+ /**
970
+ * @constructor
971
+ * @param {jasmine.Env} env
972
+ * @param actual
973
+ * @param {jasmine.NestedResults} results
974
+ */
975
+ jasmine.Matchers = function(env, actual, results) {
976
+ this.env = env;
977
+ this.actual = actual;
978
+ this.passing_message = 'Passed.';
979
+ this.results_ = results || new jasmine.NestedResults();
980
+ };
981
+
982
+ jasmine.Matchers.pp = function(str) {
983
+ return jasmine.util.htmlEscape(jasmine.pp(str));
984
+ };
985
+
986
+ jasmine.Matchers.prototype.results = function() {
987
+ return this.results_;
988
+ };
989
+
990
+ jasmine.Matchers.prototype.report = function(result, failing_message, details) {
991
+ this.results_.addResult(new jasmine.ExpectationResult(result, result ? this.passing_message : failing_message, details));
992
+ return result;
993
+ };
994
+
995
+ /**
996
+ * Matcher that compares the actual to the expected using ===.
997
+ *
998
+ * @param expected
999
+ */
1000
+ jasmine.Matchers.prototype.toBe = function(expected) {
1001
+ return this.report(this.actual === expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
1002
+ + '<br /><br />to be the same object as<br /><br />' + jasmine.Matchers.pp(this.actual)
1003
+ + '<br />');
1004
+ };
1005
+
1006
+ /**
1007
+ * Matcher that compares the actual to the expected using !==
1008
+ * @param expected
1009
+ */
1010
+ jasmine.Matchers.prototype.toNotBe = function(expected) {
1011
+ return this.report(this.actual !== expected, 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
1012
+ + '<br /><br />to be a different object from actual, but they were the same.');
1013
+ };
1014
+
1015
+ /**
1016
+ * Matcher that compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1017
+ *
1018
+ * @param expected
1019
+ */
1020
+ jasmine.Matchers.prototype.toEqual = function(expected) {
1021
+ var mismatchKeys = [];
1022
+ var mismatchValues = [];
1023
+
1024
+ var formatMismatches = function(name, array) {
1025
+ if (array.length == 0) return '';
1026
+ var errorOutput = '<br /><br />Different ' + name + ':<br />';
1027
+ for (var i = 0; i < array.length; i++) {
1028
+ errorOutput += array[i] + '<br />';
1029
+ }
1030
+ return errorOutput;
1031
+ };
1032
+
1033
+ return this.report(this.env.equals_(this.actual, expected, mismatchKeys, mismatchValues),
1034
+ 'Expected<br /><br />' + jasmine.Matchers.pp(expected)
1035
+ + '<br /><br />but got<br /><br />' + jasmine.Matchers.pp(this.actual)
1036
+ + '<br />'
1037
+ + formatMismatches('Keys', mismatchKeys)
1038
+ + formatMismatches('Values', mismatchValues), {
1039
+ matcherName: 'toEqual', expected: expected, actual: this.actual
1040
+ });
1041
+ };
1042
+
1043
+ /**
1044
+ * Matcher that compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1045
+ * @param expected
1046
+ */
1047
+ jasmine.Matchers.prototype.toNotEqual = function(expected) {
1048
+ return this.report(!this.env.equals_(this.actual, expected),
1049
+ 'Expected ' + jasmine.Matchers.pp(expected) + ' to not equal ' + jasmine.Matchers.pp(this.actual) + ', but it does.');
1050
+ };
1051
+
1052
+ /**
1053
+ * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1054
+ * a pattern or a String.
1055
+ *
1056
+ * @param reg_exp
1057
+ */
1058
+ jasmine.Matchers.prototype.toMatch = function(reg_exp) {
1059
+ return this.report((new RegExp(reg_exp).test(this.actual)),
1060
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to match ' + reg_exp + '.');
1061
+ };
1062
+
1063
+ /**
1064
+ * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1065
+ * @param reg_exp
1066
+ */
1067
+ jasmine.Matchers.prototype.toNotMatch = function(reg_exp) {
1068
+ return this.report((!new RegExp(reg_exp).test(this.actual)),
1069
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to not match ' + reg_exp + '.');
1070
+ };
1071
+
1072
+ /**
1073
+ * Matcher that compares the acutal to undefined.
1074
+ */
1075
+ jasmine.Matchers.prototype.toBeDefined = function() {
1076
+ return this.report((this.actual !== undefined),
1077
+ 'Expected a value to be defined but it was undefined.');
1078
+ };
1079
+
1080
+ /**
1081
+ * Matcher that compares the actual to null.
1082
+ *
1083
+ */
1084
+ jasmine.Matchers.prototype.toBeNull = function() {
1085
+ return this.report((this.actual === null),
1086
+ 'Expected a value to be null but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1087
+ };
1088
+
1089
+ /**
1090
+ * Matcher that boolean not-nots the actual.
1091
+ */
1092
+ jasmine.Matchers.prototype.toBeTruthy = function() {
1093
+ return this.report(!!this.actual,
1094
+ 'Expected a value to be truthy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1095
+ };
1096
+
1097
+ /**
1098
+ * Matcher that boolean nots the actual.
1099
+ */
1100
+ jasmine.Matchers.prototype.toBeFalsy = function() {
1101
+ return this.report(!this.actual,
1102
+ 'Expected a value to be falsy but it was ' + jasmine.Matchers.pp(this.actual) + '.');
1103
+ };
1104
+
1105
+ /**
1106
+ * Matcher that checks to see if the acutal, a Jasmine spy, was called.
1107
+ */
1108
+ jasmine.Matchers.prototype.wasCalled = function() {
1109
+ if (!this.actual || !this.actual.isSpy) {
1110
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
1111
+ }
1112
+ if (arguments.length > 0) {
1113
+ return this.report(false, 'wasCalled matcher does not take arguments');
1114
+ }
1115
+ return this.report((this.actual.wasCalled),
1116
+ 'Expected spy "' + this.actual.identity + '" to have been called, but it was not.');
1117
+ };
1118
+
1119
+ /**
1120
+ * Matcher that checks to see if the acutal, a Jasmine spy, was not called.
1121
+ */
1122
+ jasmine.Matchers.prototype.wasNotCalled = function() {
1123
+ if (!this.actual || !this.actual.isSpy) {
1124
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.');
1125
+ }
1126
+ return this.report((!this.actual.wasCalled),
1127
+ 'Expected spy "' + this.actual.identity + '" to not have been called, but it was.');
1128
+ };
1129
+
1130
+ /**
1131
+ * Matcher that checks to see if the acutal, a Jasmine spy, was called with a set of parameters.
1132
+ *
1133
+ * @example
1134
+ *
1135
+ */
1136
+ jasmine.Matchers.prototype.wasCalledWith = function() {
1137
+ if (!this.actual || !this.actual.isSpy) {
1138
+ return this.report(false, 'Expected a spy, but got ' + jasmine.Matchers.pp(this.actual) + '.', {
1139
+ matcherName: 'wasCalledWith'
1140
+ });
1141
+ }
1142
+
1143
+ var args = jasmine.util.argsToArray(arguments);
1144
+
1145
+ return this.report(this.env.contains_(this.actual.argsForCall, args),
1146
+ 'Expected ' + jasmine.Matchers.pp(this.actual.argsForCall) + ' to contain ' + jasmine.Matchers.pp(args) + ', but it does not.', {
1147
+ matcherName: 'wasCalledWith', expected: args, actual: this.actual.argsForCall
1148
+ });
1149
+ };
1150
+
1151
+ /**
1152
+ * Matcher that checks that the expected item is an element in the actual Array.
1153
+ *
1154
+ * @param {Object} item
1155
+ */
1156
+ jasmine.Matchers.prototype.toContain = function(item) {
1157
+ return this.report(this.env.contains_(this.actual, item),
1158
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to contain ' + jasmine.Matchers.pp(item) + ', but it does not.', {
1159
+ matcherName: 'toContain', expected: item, actual: this.actual
1160
+ });
1161
+ };
1162
+
1163
+ /**
1164
+ * Matcher that checks that the expected item is NOT an element in the actual Array.
1165
+ *
1166
+ * @param {Object} item
1167
+ */
1168
+ jasmine.Matchers.prototype.toNotContain = function(item) {
1169
+ return this.report(!this.env.contains_(this.actual, item),
1170
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' not to contain ' + jasmine.Matchers.pp(item) + ', but it does.');
1171
+ };
1172
+
1173
+ jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1174
+ return this.report(this.actual < expected,
1175
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be less than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
1176
+ };
1177
+
1178
+ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1179
+ return this.report(this.actual > expected,
1180
+ 'Expected ' + jasmine.Matchers.pp(this.actual) + ' to be greater than ' + jasmine.Matchers.pp(expected) + ', but it was not.');
1181
+ };
1182
+
1183
+ /**
1184
+ * Matcher that checks that the expected exception was thrown by the actual.
1185
+ *
1186
+ * @param {String} expectedException
1187
+ */
1188
+ jasmine.Matchers.prototype.toThrow = function(expectedException) {
1189
+ var exception = null;
1190
+ try {
1191
+ this.actual();
1192
+ } catch (e) {
1193
+ exception = e;
1194
+ }
1195
+ if (expectedException !== undefined) {
1196
+ if (exception == null) {
1197
+ return this.report(false, "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it did not.");
1198
+ }
1199
+ return this.report(
1200
+ this.env.equals_(
1201
+ exception.message || exception,
1202
+ expectedException.message || expectedException),
1203
+ "Expected function to throw " + jasmine.Matchers.pp(expectedException) + ", but it threw " + jasmine.Matchers.pp(exception) + ".");
1204
+ } else {
1205
+ return this.report(exception != null, "Expected function to throw an exception, but it did not.");
1206
+ }
1207
+ };
1208
+
1209
+ jasmine.Matchers.Any = function(expectedClass) {
1210
+ this.expectedClass = expectedClass;
1211
+ };
1212
+
1213
+ jasmine.Matchers.Any.prototype.matches = function(other) {
1214
+ if (this.expectedClass == String) {
1215
+ return typeof other == 'string' || other instanceof String;
1216
+ }
1217
+
1218
+ if (this.expectedClass == Number) {
1219
+ return typeof other == 'number' || other instanceof Number;
1220
+ }
1221
+
1222
+ if (this.expectedClass == Function) {
1223
+ return typeof other == 'function' || other instanceof Function;
1224
+ }
1225
+
1226
+ if (this.expectedClass == Object) {
1227
+ return typeof other == 'object';
1228
+ }
1229
+
1230
+ return other instanceof this.expectedClass;
1231
+ };
1232
+
1233
+ jasmine.Matchers.Any.prototype.toString = function() {
1234
+ return '<jasmine.any(' + this.expectedClass + ')>';
1235
+ };
1236
+
1237
+ /**
1238
+ * @constructor
1239
+ */
1240
+ jasmine.MultiReporter = function() {
1241
+ this.subReporters_ = [];
1242
+ };
1243
+ jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1244
+
1245
+ jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1246
+ this.subReporters_.push(reporter);
1247
+ };
1248
+
1249
+ (function() {
1250
+ var functionNames = ["reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecResults", "log"];
1251
+ for (var i = 0; i < functionNames.length; i++) {
1252
+ var functionName = functionNames[i];
1253
+ jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1254
+ return function() {
1255
+ for (var j = 0; j < this.subReporters_.length; j++) {
1256
+ var subReporter = this.subReporters_[j];
1257
+ if (subReporter[functionName]) {
1258
+ subReporter[functionName].apply(subReporter, arguments);
1259
+ }
1260
+ }
1261
+ };
1262
+ })(functionName);
1263
+ }
1264
+ })();
1265
+ /**
1266
+ * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1267
+ *
1268
+ * @constructor
1269
+ */
1270
+ jasmine.NestedResults = function() {
1271
+ /**
1272
+ * The total count of results
1273
+ */
1274
+ this.totalCount = 0;
1275
+ /**
1276
+ * Number of passed results
1277
+ */
1278
+ this.passedCount = 0;
1279
+ /**
1280
+ * Number of failed results
1281
+ */
1282
+ this.failedCount = 0;
1283
+ /**
1284
+ * Was this suite/spec skipped?
1285
+ */
1286
+ this.skipped = false;
1287
+ /**
1288
+ * @ignore
1289
+ */
1290
+ this.items_ = [];
1291
+ };
1292
+
1293
+ /**
1294
+ * Roll up the result counts.
1295
+ *
1296
+ * @param result
1297
+ */
1298
+ jasmine.NestedResults.prototype.rollupCounts = function(result) {
1299
+ this.totalCount += result.totalCount;
1300
+ this.passedCount += result.passedCount;
1301
+ this.failedCount += result.failedCount;
1302
+ };
1303
+
1304
+ /**
1305
+ * Tracks a result's message.
1306
+ * @param message
1307
+ */
1308
+ jasmine.NestedResults.prototype.log = function(message) {
1309
+ this.items_.push(new jasmine.MessageResult(message));
1310
+ };
1311
+
1312
+ /**
1313
+ * Getter for the results: message & results.
1314
+ */
1315
+ jasmine.NestedResults.prototype.getItems = function() {
1316
+ return this.items_;
1317
+ };
1318
+
1319
+ /**
1320
+ * Adds a result, tracking counts (total, passed, & failed)
1321
+ * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1322
+ */
1323
+ jasmine.NestedResults.prototype.addResult = function(result) {
1324
+ if (result.type != 'MessageResult') {
1325
+ if (result.items_) {
1326
+ this.rollupCounts(result);
1327
+ } else {
1328
+ this.totalCount++;
1329
+ if (result.passed()) {
1330
+ this.passedCount++;
1331
+ } else {
1332
+ this.failedCount++;
1333
+ }
1334
+ }
1335
+ }
1336
+ this.items_.push(result);
1337
+ };
1338
+
1339
+ /**
1340
+ * @returns {Boolean} True if <b>everything</b> below passed
1341
+ */
1342
+ jasmine.NestedResults.prototype.passed = function() {
1343
+ return this.passedCount === this.totalCount;
1344
+ };
1345
+ /**
1346
+ * Base class for pretty printing for expectation results.
1347
+ */
1348
+ jasmine.PrettyPrinter = function() {
1349
+ this.ppNestLevel_ = 0;
1350
+ };
1351
+
1352
+ /**
1353
+ * Formats a value in a nice, human-readable string.
1354
+ *
1355
+ * @param value
1356
+ * @returns {String}
1357
+ */
1358
+ jasmine.PrettyPrinter.prototype.format = function(value) {
1359
+ if (this.ppNestLevel_ > 40) {
1360
+ // return '(jasmine.pp nested too deeply!)';
1361
+ throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
1362
+ }
1363
+
1364
+ this.ppNestLevel_++;
1365
+ try {
1366
+ if (value === undefined) {
1367
+ this.emitScalar('undefined');
1368
+ } else if (value === null) {
1369
+ this.emitScalar('null');
1370
+ } else if (value.navigator && value.frames && value.setTimeout) {
1371
+ this.emitScalar('<window>');
1372
+ } else if (value instanceof jasmine.Matchers.Any) {
1373
+ this.emitScalar(value.toString());
1374
+ } else if (typeof value === 'string') {
1375
+ this.emitString(value);
1376
+ } else if (typeof value === 'function') {
1377
+ this.emitScalar('Function');
1378
+ } else if (typeof value.nodeType === 'number') {
1379
+ this.emitScalar('HTMLNode');
1380
+ } else if (value instanceof Date) {
1381
+ this.emitScalar('Date(' + value + ')');
1382
+ } else if (value.__Jasmine_been_here_before__) {
1383
+ this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1384
+ } else if (jasmine.isArray_(value) || typeof value == 'object') {
1385
+ value.__Jasmine_been_here_before__ = true;
1386
+ if (jasmine.isArray_(value)) {
1387
+ this.emitArray(value);
1388
+ } else {
1389
+ this.emitObject(value);
1390
+ }
1391
+ delete value.__Jasmine_been_here_before__;
1392
+ } else {
1393
+ this.emitScalar(value.toString());
1394
+ }
1395
+ } finally {
1396
+ this.ppNestLevel_--;
1397
+ }
1398
+ };
1399
+
1400
+ jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1401
+ for (var property in obj) {
1402
+ if (property == '__Jasmine_been_here_before__') continue;
1403
+ fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false);
1404
+ }
1405
+ };
1406
+
1407
+ jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1408
+ jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1409
+ jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1410
+ jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1411
+
1412
+ jasmine.StringPrettyPrinter = function() {
1413
+ jasmine.PrettyPrinter.call(this);
1414
+
1415
+ this.string = '';
1416
+ };
1417
+ jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1418
+
1419
+ jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1420
+ this.append(value);
1421
+ };
1422
+
1423
+ jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1424
+ this.append("'" + value + "'");
1425
+ };
1426
+
1427
+ jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1428
+ this.append('[ ');
1429
+ for (var i = 0; i < array.length; i++) {
1430
+ if (i > 0) {
1431
+ this.append(', ');
1432
+ }
1433
+ this.format(array[i]);
1434
+ }
1435
+ this.append(' ]');
1436
+ };
1437
+
1438
+ jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1439
+ var self = this;
1440
+ this.append('{ ');
1441
+ var first = true;
1442
+
1443
+ this.iterateObject(obj, function(property, isGetter) {
1444
+ if (first) {
1445
+ first = false;
1446
+ } else {
1447
+ self.append(', ');
1448
+ }
1449
+
1450
+ self.append(property);
1451
+ self.append(' : ');
1452
+ if (isGetter) {
1453
+ self.append('<getter>');
1454
+ } else {
1455
+ self.format(obj[property]);
1456
+ }
1457
+ });
1458
+
1459
+ this.append(' }');
1460
+ };
1461
+
1462
+ jasmine.StringPrettyPrinter.prototype.append = function(value) {
1463
+ this.string += value;
1464
+ };
1465
+ jasmine.Queue = function(env) {
1466
+ this.env = env;
1467
+ this.blocks = [];
1468
+ this.running = false;
1469
+ this.index = 0;
1470
+ this.offset = 0;
1471
+ };
1472
+
1473
+ jasmine.Queue.prototype.addBefore = function(block) {
1474
+ this.blocks.unshift(block);
1475
+ };
1476
+
1477
+ jasmine.Queue.prototype.add = function(block) {
1478
+ this.blocks.push(block);
1479
+ };
1480
+
1481
+ jasmine.Queue.prototype.insertNext = function(block) {
1482
+ this.blocks.splice((this.index + this.offset + 1), 0, block);
1483
+ this.offset++;
1484
+ };
1485
+
1486
+ jasmine.Queue.prototype.start = function(onComplete) {
1487
+ this.running = true;
1488
+ this.onComplete = onComplete;
1489
+ this.next_();
1490
+ };
1491
+
1492
+ jasmine.Queue.prototype.isRunning = function() {
1493
+ return this.running;
1494
+ };
1495
+
1496
+ jasmine.Queue.LOOP_DONT_RECURSE = true;
1497
+
1498
+ jasmine.Queue.prototype.next_ = function() {
1499
+ var self = this;
1500
+ var goAgain = true;
1501
+
1502
+ while (goAgain) {
1503
+ goAgain = false;
1504
+
1505
+ if (self.index < self.blocks.length) {
1506
+ var calledSynchronously = true;
1507
+ var completedSynchronously = false;
1508
+
1509
+ var onComplete = function () {
1510
+ if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
1511
+ completedSynchronously = true;
1512
+ return;
1513
+ }
1514
+
1515
+ self.offset = 0;
1516
+ self.index++;
1517
+
1518
+ var now = new Date().getTime();
1519
+ if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
1520
+ self.env.lastUpdate = now;
1521
+ self.env.setTimeout(function() {
1522
+ self.next_();
1523
+ }, 0);
1524
+ } else {
1525
+ if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
1526
+ goAgain = true;
1527
+ } else {
1528
+ self.next_();
1529
+ }
1530
+ }
1531
+ };
1532
+ self.blocks[self.index].execute(onComplete);
1533
+
1534
+ calledSynchronously = false;
1535
+ if (completedSynchronously) {
1536
+ onComplete();
1537
+ }
1538
+
1539
+ } else {
1540
+ self.running = false;
1541
+ if (self.onComplete) {
1542
+ self.onComplete();
1543
+ }
1544
+ }
1545
+ }
1546
+ };
1547
+
1548
+ jasmine.Queue.prototype.results = function() {
1549
+ var results = new jasmine.NestedResults();
1550
+ for (var i = 0; i < this.blocks.length; i++) {
1551
+ if (this.blocks[i].results) {
1552
+ results.addResult(this.blocks[i].results());
1553
+ }
1554
+ }
1555
+ return results;
1556
+ };
1557
+
1558
+
1559
+ /* JasmineReporters.reporter
1560
+ * Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to
1561
+ * descendants of this object to do something with the results (see json_reporter.js)
1562
+ */
1563
+ jasmine.Reporters = {};
1564
+
1565
+ jasmine.Reporters.reporter = function(callbacks) {
1566
+ var that = {
1567
+ callbacks: callbacks || {},
1568
+
1569
+ doCallback: function(callback, results) {
1570
+ if (callback) {
1571
+ callback(results);
1572
+ }
1573
+ },
1574
+
1575
+ reportRunnerResults: function(runner) {
1576
+ that.doCallback(that.callbacks.runnerCallback, runner);
1577
+ },
1578
+ reportSuiteResults: function(suite) {
1579
+ that.doCallback(that.callbacks.suiteCallback, suite);
1580
+ },
1581
+ reportSpecResults: function(spec) {
1582
+ that.doCallback(that.callbacks.specCallback, spec);
1583
+ },
1584
+ log: function (str) {
1585
+ if (console && console.log) console.log(str);
1586
+ }
1587
+ };
1588
+
1589
+ return that;
1590
+ };
1591
+
1592
+ /**
1593
+ * Runner
1594
+ *
1595
+ * @constructor
1596
+ * @param {jasmine.Env} env
1597
+ */
1598
+ jasmine.Runner = function(env) {
1599
+ var self = this;
1600
+ self.env = env;
1601
+ self.queue = new jasmine.Queue(env);
1602
+ self.before_ = [];
1603
+ self.after_ = [];
1604
+ self.suites_ = [];
1605
+ };
1606
+
1607
+ jasmine.Runner.prototype.execute = function() {
1608
+ var self = this;
1609
+ if (self.env.reporter.reportRunnerStarting) {
1610
+ self.env.reporter.reportRunnerStarting(this);
1611
+ }
1612
+ self.queue.start(function () {
1613
+ self.finishCallback();
1614
+ });
1615
+ };
1616
+
1617
+ jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
1618
+ beforeEachFunction.typeName = 'beforeEach';
1619
+ this.before_.push(beforeEachFunction);
1620
+ };
1621
+
1622
+ jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
1623
+ afterEachFunction.typeName = 'afterEach';
1624
+ this.after_.push(afterEachFunction);
1625
+ };
1626
+
1627
+
1628
+ jasmine.Runner.prototype.finishCallback = function() {
1629
+ this.env.reporter.reportRunnerResults(this);
1630
+ };
1631
+
1632
+ jasmine.Runner.prototype.addSuite = function(suite) {
1633
+ this.suites_.push(suite);
1634
+ };
1635
+
1636
+ jasmine.Runner.prototype.add = function(block) {
1637
+ if (block instanceof jasmine.Suite) {
1638
+ this.addSuite(block);
1639
+ }
1640
+ this.queue.add(block);
1641
+ };
1642
+
1643
+ jasmine.Runner.prototype.specs = function () {
1644
+ var suites = this.suites();
1645
+ var specs = [];
1646
+ for (var i = 0; i < suites.length; i++) {
1647
+ specs = specs.concat(suites[i].specs());
1648
+ }
1649
+ return specs;
1650
+ };
1651
+
1652
+
1653
+ jasmine.Runner.prototype.suites = function() {
1654
+ return this.suites_;
1655
+ };
1656
+
1657
+ jasmine.Runner.prototype.results = function() {
1658
+ return this.queue.results();
1659
+ };
1660
+ /**
1661
+ * Internal representation of a Jasmine specification, or test.
1662
+ *
1663
+ * @constructor
1664
+ * @param {jasmine.Env} env
1665
+ * @param {jasmine.Suite} suite
1666
+ * @param {String} description
1667
+ */
1668
+ jasmine.Spec = function(env, suite, description) {
1669
+ if (!env) {
1670
+ throw new Error('jasmine.Env() required');
1671
+ }
1672
+ ;
1673
+ if (!suite) {
1674
+ throw new Error('jasmine.Suite() required');
1675
+ }
1676
+ ;
1677
+ var spec = this;
1678
+ spec.id = env.nextSpecId ? env.nextSpecId() : null;
1679
+ spec.env = env;
1680
+ spec.suite = suite;
1681
+ spec.description = description;
1682
+ spec.queue = new jasmine.Queue(env);
1683
+
1684
+ spec.afterCallbacks = [];
1685
+ spec.spies_ = [];
1686
+
1687
+ spec.results_ = new jasmine.NestedResults();
1688
+ spec.results_.description = description;
1689
+ spec.matchersClass = null;
1690
+ };
1691
+
1692
+ jasmine.Spec.prototype.getFullName = function() {
1693
+ return this.suite.getFullName() + ' ' + this.description + '.';
1694
+ };
1695
+
1696
+
1697
+ jasmine.Spec.prototype.results = function() {
1698
+ return this.results_;
1699
+ };
1700
+
1701
+ jasmine.Spec.prototype.log = function(message) {
1702
+ return this.results_.log(message);
1703
+ };
1704
+
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.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.expect = function(actual) {
1720
+ return new (this.getMatchersClass_())(this.env, actual, this.results_);
1721
+ };
1722
+
1723
+ jasmine.Spec.prototype.waits = function(timeout) {
1724
+ var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
1725
+ this.addToQueue(waitsFunc);
1726
+ return this;
1727
+ };
1728
+
1729
+ jasmine.Spec.prototype.waitsFor = function(timeout, latchFunction, timeoutMessage) {
1730
+ var waitsForFunc = new jasmine.WaitsForBlock(this.env, timeout, latchFunction, timeoutMessage, this);
1731
+ this.addToQueue(waitsForFunc);
1732
+ return this;
1733
+ };
1734
+
1735
+ jasmine.Spec.prototype.fail = function (e) {
1736
+ this.results_.addResult(new jasmine.ExpectationResult(false, e ? jasmine.util.formatException(e) : null, null));
1737
+ };
1738
+
1739
+ jasmine.Spec.prototype.getMatchersClass_ = function() {
1740
+ return this.matchersClass || jasmine.Matchers;
1741
+ };
1742
+
1743
+ jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
1744
+ var parent = this.getMatchersClass_();
1745
+ var newMatchersClass = function() {
1746
+ parent.apply(this, arguments);
1747
+ };
1748
+ jasmine.util.inherit(newMatchersClass, parent);
1749
+ for (var method in matchersPrototype) {
1750
+ newMatchersClass.prototype[method] = matchersPrototype[method];
1751
+ }
1752
+ this.matchersClass = newMatchersClass;
1753
+ };
1754
+
1755
+ jasmine.Spec.prototype.finishCallback = function() {
1756
+ this.env.reporter.reportSpecResults(this);
1757
+ };
1758
+
1759
+ jasmine.Spec.prototype.finish = function(onComplete) {
1760
+ this.removeAllSpies();
1761
+ this.finishCallback();
1762
+ if (onComplete) {
1763
+ onComplete();
1764
+ }
1765
+ };
1766
+
1767
+ jasmine.Spec.prototype.after = function(doAfter, test) {
1768
+
1769
+ if (this.queue.isRunning()) {
1770
+ this.queue.add(new jasmine.Block(this.env, doAfter, this));
1771
+ } else {
1772
+ this.afterCallbacks.unshift(doAfter);
1773
+ }
1774
+ };
1775
+
1776
+ jasmine.Spec.prototype.execute = function(onComplete) {
1777
+ var spec = this;
1778
+ if (!spec.env.specFilter(spec)) {
1779
+ spec.results_.skipped = true;
1780
+ spec.finish(onComplete);
1781
+ return;
1782
+ }
1783
+ this.env.reporter.log('>> Jasmine Running ' + this.suite.description + ' ' + this.description + '...');
1784
+
1785
+ spec.env.currentSpec = spec;
1786
+
1787
+ spec.addBeforesAndAftersToQueue();
1788
+
1789
+ spec.queue.start(function () {
1790
+ spec.finish(onComplete);
1791
+ });
1792
+ };
1793
+
1794
+ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
1795
+ var runner = this.env.currentRunner();
1796
+ for (var suite = this.suite; suite; suite = suite.parentSuite) {
1797
+ for (var i = 0; i < suite.before_.length; i++) {
1798
+ this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
1799
+ }
1800
+ }
1801
+ for (var i = 0; i < runner.before_.length; i++) {
1802
+ this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
1803
+ }
1804
+ for (i = 0; i < this.afterCallbacks.length; i++) {
1805
+ this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
1806
+ }
1807
+ for (suite = this.suite; suite; suite = suite.parentSuite) {
1808
+ for (var i = 0; i < suite.after_.length; i++) {
1809
+ this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
1810
+ }
1811
+ }
1812
+ for (var i = 0; i < runner.after_.length; i++) {
1813
+ this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
1814
+ }
1815
+ };
1816
+
1817
+ jasmine.Spec.prototype.explodes = function() {
1818
+ throw 'explodes function should not have been called';
1819
+ };
1820
+
1821
+ jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
1822
+ if (obj == undefined) {
1823
+ throw "spyOn could not find an object to spy upon for " + methodName + "()";
1824
+ }
1825
+
1826
+ if (!ignoreMethodDoesntExist && obj[methodName] === undefined) {
1827
+ throw methodName + '() method does not exist';
1828
+ }
1829
+
1830
+ if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
1831
+ throw new Error(methodName + ' has already been spied upon');
1832
+ }
1833
+
1834
+ var spyObj = jasmine.createSpy(methodName);
1835
+
1836
+ this.spies_.push(spyObj);
1837
+ spyObj.baseObj = obj;
1838
+ spyObj.methodName = methodName;
1839
+ spyObj.originalValue = obj[methodName];
1840
+
1841
+ obj[methodName] = spyObj;
1842
+
1843
+ return spyObj;
1844
+ };
1845
+
1846
+ jasmine.Spec.prototype.removeAllSpies = function() {
1847
+ for (var i = 0; i < this.spies_.length; i++) {
1848
+ var spy = this.spies_[i];
1849
+ spy.baseObj[spy.methodName] = spy.originalValue;
1850
+ }
1851
+ this.spies_ = [];
1852
+ };
1853
+
1854
+ /**
1855
+ * Internal representation of a Jasmine suite.
1856
+ *
1857
+ * @constructor
1858
+ * @param {jasmine.Env} env
1859
+ * @param {String} description
1860
+ * @param {Function} specDefinitions
1861
+ * @param {jasmine.Suite} parentSuite
1862
+ */
1863
+ jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
1864
+ var self = this;
1865
+ self.id = env.nextSuiteId ? env.nextSuiteId() : null;
1866
+ self.description = description;
1867
+ self.queue = new jasmine.Queue(env);
1868
+ self.parentSuite = parentSuite;
1869
+ self.env = env;
1870
+ self.before_ = [];
1871
+ self.after_ = [];
1872
+ self.specs_ = [];
1873
+ };
1874
+
1875
+ jasmine.Suite.prototype.getFullName = function() {
1876
+ var fullName = this.description;
1877
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
1878
+ fullName = parentSuite.description + ' ' + fullName;
1879
+ }
1880
+ return fullName;
1881
+ };
1882
+
1883
+ jasmine.Suite.prototype.finish = function(onComplete) {
1884
+ this.env.reporter.reportSuiteResults(this);
1885
+ this.finished = true;
1886
+ if (typeof(onComplete) == 'function') {
1887
+ onComplete();
1888
+ }
1889
+ };
1890
+
1891
+ jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
1892
+ beforeEachFunction.typeName = 'beforeEach';
1893
+ this.before_.push(beforeEachFunction);
1894
+ };
1895
+
1896
+ jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
1897
+ afterEachFunction.typeName = 'afterEach';
1898
+ this.after_.push(afterEachFunction);
1899
+ };
1900
+
1901
+ jasmine.Suite.prototype.results = function() {
1902
+ return this.queue.results();
1903
+ };
1904
+
1905
+ jasmine.Suite.prototype.add = function(block) {
1906
+ if (block instanceof jasmine.Suite) {
1907
+ this.env.currentRunner().addSuite(block);
1908
+ } else {
1909
+ this.specs_.push(block);
1910
+ }
1911
+ this.queue.add(block);
1912
+ };
1913
+
1914
+ jasmine.Suite.prototype.specs = function() {
1915
+ return this.specs_;
1916
+ };
1917
+
1918
+ jasmine.Suite.prototype.execute = function(onComplete) {
1919
+ var self = this;
1920
+ this.queue.start(function () {
1921
+ self.finish(onComplete);
1922
+ });
1923
+ };
1924
+ jasmine.WaitsBlock = function(env, timeout, spec) {
1925
+ this.timeout = timeout;
1926
+ jasmine.Block.call(this, env, null, spec);
1927
+ };
1928
+
1929
+ jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
1930
+
1931
+ jasmine.WaitsBlock.prototype.execute = function (onComplete) {
1932
+ this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
1933
+ this.env.setTimeout(function () {
1934
+ onComplete();
1935
+ }, this.timeout);
1936
+ };
1937
+ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
1938
+ this.timeout = timeout;
1939
+ this.latchFunction = latchFunction;
1940
+ this.message = message;
1941
+ this.totalTimeSpentWaitingForLatch = 0;
1942
+ jasmine.Block.call(this, env, null, spec);
1943
+ };
1944
+
1945
+ jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
1946
+
1947
+ jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 100;
1948
+
1949
+ jasmine.WaitsForBlock.prototype.execute = function (onComplete) {
1950
+ var self = this;
1951
+ self.env.reporter.log('>> Jasmine waiting for ' + (self.message || 'something to happen'));
1952
+ var latchFunctionResult;
1953
+ try {
1954
+ latchFunctionResult = self.latchFunction.apply(self.spec);
1955
+ } catch (e) {
1956
+ self.spec.fail(e);
1957
+ onComplete();
1958
+ return;
1959
+ }
1960
+
1961
+ if (latchFunctionResult) {
1962
+ onComplete();
1963
+ } else if (self.totalTimeSpentWaitingForLatch >= self.timeout) {
1964
+ var message = 'timed out after ' + self.timeout + ' msec waiting for ' + (self.message || 'something to happen');
1965
+ self.spec.fail({
1966
+ name: 'timeout',
1967
+ message: message
1968
+ });
1969
+ self.spec._next();
1970
+ } else {
1971
+ self.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
1972
+ self.env.setTimeout(function () { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
1973
+ }
1974
+ };
1975
+ // Mock setTimeout, clearTimeout
1976
+ // Contributed by Pivotal Computer Systems, www.pivotalsf.com
1977
+
1978
+ jasmine.FakeTimer = function() {
1979
+ this.reset();
1980
+
1981
+ var self = this;
1982
+ self.setTimeout = function(funcToCall, millis) {
1983
+ self.timeoutsMade++;
1984
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1985
+ return self.timeoutsMade;
1986
+ };
1987
+
1988
+ self.setInterval = function(funcToCall, millis) {
1989
+ self.timeoutsMade++;
1990
+ self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1991
+ return self.timeoutsMade;
1992
+ };
1993
+
1994
+ self.clearTimeout = function(timeoutKey) {
1995
+ self.scheduledFunctions[timeoutKey] = undefined;
1996
+ };
1997
+
1998
+ self.clearInterval = function(timeoutKey) {
1999
+ self.scheduledFunctions[timeoutKey] = undefined;
2000
+ };
2001
+
2002
+ };
2003
+
2004
+ jasmine.FakeTimer.prototype.reset = function() {
2005
+ this.timeoutsMade = 0;
2006
+ this.scheduledFunctions = {};
2007
+ this.nowMillis = 0;
2008
+ };
2009
+
2010
+ jasmine.FakeTimer.prototype.tick = function(millis) {
2011
+ var oldMillis = this.nowMillis;
2012
+ var newMillis = oldMillis + millis;
2013
+ this.runFunctionsWithinRange(oldMillis, newMillis);
2014
+ this.nowMillis = newMillis;
2015
+ };
2016
+
2017
+ jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
2018
+ var scheduledFunc;
2019
+ var funcsToRun = [];
2020
+ for (var timeoutKey in this.scheduledFunctions) {
2021
+ scheduledFunc = this.scheduledFunctions[timeoutKey];
2022
+ if (scheduledFunc != undefined &&
2023
+ scheduledFunc.runAtMillis >= oldMillis &&
2024
+ scheduledFunc.runAtMillis <= nowMillis) {
2025
+ funcsToRun.push(scheduledFunc);
2026
+ this.scheduledFunctions[timeoutKey] = undefined;
2027
+ }
2028
+ }
2029
+
2030
+ if (funcsToRun.length > 0) {
2031
+ funcsToRun.sort(function(a, b) {
2032
+ return a.runAtMillis - b.runAtMillis;
2033
+ });
2034
+ for (var i = 0; i < funcsToRun.length; ++i) {
2035
+ try {
2036
+ var funcToRun = funcsToRun[i];
2037
+ this.nowMillis = funcToRun.runAtMillis;
2038
+ funcToRun.funcToCall();
2039
+ if (funcToRun.recurring) {
2040
+ this.scheduleFunction(funcToRun.timeoutKey,
2041
+ funcToRun.funcToCall,
2042
+ funcToRun.millis,
2043
+ true);
2044
+ }
2045
+ } catch(e) {
2046
+ }
2047
+ }
2048
+ this.runFunctionsWithinRange(oldMillis, nowMillis);
2049
+ }
2050
+ };
2051
+
2052
+ jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
2053
+ this.scheduledFunctions[timeoutKey] = {
2054
+ runAtMillis: this.nowMillis + millis,
2055
+ funcToCall: funcToCall,
2056
+ recurring: recurring,
2057
+ timeoutKey: timeoutKey,
2058
+ millis: millis
2059
+ };
2060
+ };
2061
+
2062
+
2063
+ jasmine.Clock = {
2064
+ defaultFakeTimer: new jasmine.FakeTimer(),
2065
+
2066
+ reset: function() {
2067
+ jasmine.Clock.assertInstalled();
2068
+ jasmine.Clock.defaultFakeTimer.reset();
2069
+ },
2070
+
2071
+ tick: function(millis) {
2072
+ jasmine.Clock.assertInstalled();
2073
+ jasmine.Clock.defaultFakeTimer.tick(millis);
2074
+ },
2075
+
2076
+ runFunctionsWithinRange: function(oldMillis, nowMillis) {
2077
+ jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
2078
+ },
2079
+
2080
+ scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
2081
+ jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
2082
+ },
2083
+
2084
+ useMock: function() {
2085
+ var spec = jasmine.getEnv().currentSpec;
2086
+ spec.after(jasmine.Clock.uninstallMock);
2087
+
2088
+ jasmine.Clock.installMock();
2089
+ },
2090
+
2091
+ installMock: function() {
2092
+ jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
2093
+ },
2094
+
2095
+ uninstallMock: function() {
2096
+ jasmine.Clock.assertInstalled();
2097
+ jasmine.Clock.installed = jasmine.Clock.real;
2098
+ },
2099
+
2100
+ real: {
2101
+ setTimeout: window.setTimeout,
2102
+ clearTimeout: window.clearTimeout,
2103
+ setInterval: window.setInterval,
2104
+ clearInterval: window.clearInterval
2105
+ },
2106
+
2107
+ assertInstalled: function() {
2108
+ if (jasmine.Clock.installed != jasmine.Clock.defaultFakeTimer) {
2109
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
2110
+ }
2111
+ },
2112
+
2113
+ installed: null
2114
+ };
2115
+ jasmine.Clock.installed = jasmine.Clock.real;
2116
+
2117
+ //else for IE support
2118
+ window.setTimeout = function(funcToCall, millis) {
2119
+ if (jasmine.Clock.installed.setTimeout.apply) {
2120
+ return jasmine.Clock.installed.setTimeout.apply(this, arguments);
2121
+ } else {
2122
+ return jasmine.Clock.installed.setTimeout(funcToCall, millis);
2123
+ }
2124
+ };
2125
+
2126
+ window.setInterval = function(funcToCall, millis) {
2127
+ if (jasmine.Clock.installed.setInterval.apply) {
2128
+ return jasmine.Clock.installed.setInterval.apply(this, arguments);
2129
+ } else {
2130
+ return jasmine.Clock.installed.setInterval(funcToCall, millis);
2131
+ }
2132
+ };
2133
+
2134
+ window.clearTimeout = function(timeoutKey) {
2135
+ if (jasmine.Clock.installed.clearTimeout.apply) {
2136
+ return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
2137
+ } else {
2138
+ return jasmine.Clock.installed.clearTimeout(timeoutKey);
2139
+ }
2140
+ };
2141
+
2142
+ window.clearInterval = function(timeoutKey) {
2143
+ if (jasmine.Clock.installed.clearTimeout.apply) {
2144
+ return jasmine.Clock.installed.clearInterval.apply(this, arguments);
2145
+ } else {
2146
+ return jasmine.Clock.installed.clearInterval(timeoutKey);
2147
+ }
2148
+ };
2149
+