jasmine-core 1.3.1 → 2.0.0.rc2

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 (73) hide show
  1. data/lib/jasmine-core.rb +14 -1
  2. data/lib/jasmine-core/boot.js +131 -0
  3. data/lib/jasmine-core/boot/boot.js +109 -0
  4. data/lib/jasmine-core/example/spec/PlayerSpec.js +2 -2
  5. data/lib/jasmine-core/example/spec/SpecHelper.js +14 -8
  6. data/lib/jasmine-core/jasmine-html.js +289 -616
  7. data/lib/jasmine-core/jasmine.css +52 -80
  8. data/lib/jasmine-core/jasmine.js +1972 -2211
  9. data/lib/jasmine-core/spec/console/ConsoleReporterSpec.js +161 -386
  10. data/lib/jasmine-core/spec/core/AnySpec.js +45 -0
  11. data/lib/jasmine-core/spec/core/CallTrackerSpec.js +105 -0
  12. data/lib/jasmine-core/spec/core/ClockSpec.js +314 -0
  13. data/lib/jasmine-core/spec/core/CustomMatchersSpec.js +96 -97
  14. data/lib/jasmine-core/spec/core/DelayedFunctionSchedulerSpec.js +179 -0
  15. data/lib/jasmine-core/spec/core/EnvSpec.js +454 -102
  16. data/lib/jasmine-core/spec/core/ExceptionFormatterSpec.js +56 -0
  17. data/lib/jasmine-core/spec/core/ExceptionsSpec.js +15 -126
  18. data/lib/jasmine-core/spec/core/ExpectationResultSpec.js +61 -0
  19. data/lib/jasmine-core/spec/core/ExpectationSpec.js +320 -0
  20. data/lib/jasmine-core/spec/core/JsApiReporterSpec.js +150 -38
  21. data/lib/jasmine-core/spec/core/ObjectContainingSpec.js +64 -0
  22. data/lib/jasmine-core/spec/core/PrettyPrintSpec.js +43 -42
  23. data/lib/jasmine-core/spec/core/QueueRunnerSpec.js +147 -0
  24. data/lib/jasmine-core/spec/core/ReportDispatcherSpec.js +40 -0
  25. data/lib/jasmine-core/spec/core/SpecRunningSpec.js +92 -1075
  26. data/lib/jasmine-core/spec/core/SpecSpec.js +215 -95
  27. data/lib/jasmine-core/spec/core/SpySpec.js +28 -196
  28. data/lib/jasmine-core/spec/core/SpyStrategySpec.js +101 -0
  29. data/lib/jasmine-core/spec/core/SuiteSpec.js +216 -106
  30. data/lib/jasmine-core/spec/core/TimerSpec.js +13 -0
  31. data/lib/jasmine-core/spec/core/UtilSpec.js +19 -30
  32. data/lib/jasmine-core/spec/core/matchers/matchersUtilSpec.js +219 -0
  33. data/lib/jasmine-core/spec/core/matchers/toBeCloseToSpec.js +51 -0
  34. data/lib/jasmine-core/spec/core/matchers/toBeDefinedSpec.js +18 -0
  35. data/lib/jasmine-core/spec/core/matchers/toBeFalsySpec.js +38 -0
  36. data/lib/jasmine-core/spec/core/matchers/toBeGreaterThanSpec.js +19 -0
  37. data/lib/jasmine-core/spec/core/matchers/toBeLessThanSpec.js +20 -0
  38. data/lib/jasmine-core/spec/core/matchers/toBeNaNSpec.js +36 -0
  39. data/lib/jasmine-core/spec/core/matchers/toBeNullSpec.js +17 -0
  40. data/lib/jasmine-core/spec/core/matchers/toBeSpec.js +17 -0
  41. data/lib/jasmine-core/spec/core/matchers/toBeTruthySpec.js +38 -0
  42. data/lib/jasmine-core/spec/core/matchers/toBeUndefinedSpec.js +17 -0
  43. data/lib/jasmine-core/spec/core/matchers/toContainSpec.js +24 -0
  44. data/lib/jasmine-core/spec/core/matchers/toEqualSpec.js +28 -0
  45. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledSpec.js +46 -0
  46. data/lib/jasmine-core/spec/core/matchers/toHaveBeenCalledWithSpec.js +57 -0
  47. data/lib/jasmine-core/spec/core/matchers/toMatchSpec.js +34 -0
  48. data/lib/jasmine-core/spec/core/matchers/toThrowErrorSpec.js +280 -0
  49. data/lib/jasmine-core/spec/core/matchers/toThrowSpec.js +98 -0
  50. data/lib/jasmine-core/spec/helpers/BrowserFlags.js +19 -0
  51. data/lib/jasmine-core/spec/html/HtmlReporterSpec.js +494 -0
  52. data/lib/jasmine-core/spec/html/HtmlSpecFilterSpec.js +18 -0
  53. data/lib/jasmine-core/spec/html/MatchersHtmlSpec.js +8 -8
  54. data/lib/jasmine-core/spec/html/PrettyPrintHtmlSpec.js +3 -3
  55. data/lib/jasmine-core/spec/html/QueryStringSpec.js +43 -0
  56. data/lib/jasmine-core/spec/html/ResultsNodeSpec.js +62 -0
  57. data/lib/jasmine-core/spec/node_suite.js +137 -79
  58. data/lib/jasmine-core/spec/performance/performance_test.js +10 -0
  59. data/lib/jasmine-core/spec/support/dev_boot.js +118 -0
  60. data/lib/jasmine-core/version.rb +5 -2
  61. metadata +47 -103
  62. data/lib/jasmine-core/example/SpecRunner.html +0 -54
  63. data/lib/jasmine-core/spec/core/BaseSpec.js +0 -27
  64. data/lib/jasmine-core/spec/core/MatchersSpec.js +0 -1157
  65. data/lib/jasmine-core/spec/core/MockClockSpec.js +0 -38
  66. data/lib/jasmine-core/spec/core/MultiReporterSpec.js +0 -45
  67. data/lib/jasmine-core/spec/core/NestedResultsSpec.js +0 -54
  68. data/lib/jasmine-core/spec/core/QueueSpec.js +0 -23
  69. data/lib/jasmine-core/spec/core/ReporterSpec.js +0 -56
  70. data/lib/jasmine-core/spec/core/RunnerSpec.js +0 -280
  71. data/lib/jasmine-core/spec/core/WaitsForBlockSpec.js +0 -118
  72. data/lib/jasmine-core/spec/html/HTMLReporterSpec.js +0 -209
  73. data/lib/jasmine-core/spec/html/TrivialReporterSpec.js +0 -239
@@ -1,82 +1,54 @@
1
1
  body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2
2
 
3
- #HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4
- #HTMLReporter a { text-decoration: none; }
5
- #HTMLReporter a:hover { text-decoration: underline; }
6
- #HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
7
- #HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
8
- #HTMLReporter #jasmine_content { position: fixed; right: 100%; }
9
- #HTMLReporter .version { color: #aaaaaa; }
10
- #HTMLReporter .banner { margin-top: 14px; }
11
- #HTMLReporter .duration { color: #aaaaaa; float: right; }
12
- #HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
13
- #HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
14
- #HTMLReporter .symbolSummary li.passed { font-size: 14px; }
15
- #HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
16
- #HTMLReporter .symbolSummary li.failed { line-height: 9px; }
17
- #HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
18
- #HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
19
- #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
20
- #HTMLReporter .symbolSummary li.pending { line-height: 11px; }
21
- #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
22
- #HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
23
- #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
24
- #HTMLReporter .runningAlert { background-color: #666666; }
25
- #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
26
- #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
27
- #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
28
- #HTMLReporter .passingAlert { background-color: #a6b779; }
29
- #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
30
- #HTMLReporter .failingAlert { background-color: #cf867e; }
31
- #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
32
- #HTMLReporter .results { margin-top: 14px; }
33
- #HTMLReporter #details { display: none; }
34
- #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
35
- #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36
- #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37
- #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38
- #HTMLReporter.showDetails .summary { display: none; }
39
- #HTMLReporter.showDetails #details { display: block; }
40
- #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41
- #HTMLReporter .summary { margin-top: 14px; }
42
- #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
43
- #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
44
- #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
45
- #HTMLReporter .description + .suite { margin-top: 0; }
46
- #HTMLReporter .suite { margin-top: 14px; }
47
- #HTMLReporter .suite a { color: #333333; }
48
- #HTMLReporter #details .specDetail { margin-bottom: 28px; }
49
- #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
50
- #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
51
- #HTMLReporter .resultMessage span.result { display: block; }
52
- #HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
53
-
54
- #TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
55
- #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
56
- #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
57
- #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
58
- #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
59
- #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
60
- #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
61
- #TrivialReporter .runner.running { background-color: yellow; }
62
- #TrivialReporter .options { text-align: right; font-size: .8em; }
63
- #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
64
- #TrivialReporter .suite .suite { margin: 5px; }
65
- #TrivialReporter .suite.passed { background-color: #dfd; }
66
- #TrivialReporter .suite.failed { background-color: #fdd; }
67
- #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
68
- #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
69
- #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
70
- #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
71
- #TrivialReporter .spec.skipped { background-color: #bbb; }
72
- #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
73
- #TrivialReporter .passed { background-color: #cfc; display: none; }
74
- #TrivialReporter .failed { background-color: #fbb; }
75
- #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
76
- #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
77
- #TrivialReporter .resultMessage .mismatch { color: black; }
78
- #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
79
- #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
80
- #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
81
- #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
82
- #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
3
+ .html-reporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4
+ .html-reporter a { text-decoration: none; }
5
+ .html-reporter a:hover { text-decoration: underline; }
6
+ .html-reporter p, .html-reporter h1, .html-reporter h2, .html-reporter h3, .html-reporter h4, .html-reporter h5, .html-reporter h6 { margin: 0; line-height: 14px; }
7
+ .html-reporter .banner, .html-reporter .symbol-summary, .html-reporter .summary, .html-reporter .result-message, .html-reporter .spec .description, .html-reporter .spec-detail .description, .html-reporter .alert .bar, .html-reporter .stack-trace { padding-left: 9px; padding-right: 9px; }
8
+ .html-reporter .banner .version { margin-left: 14px; }
9
+ .html-reporter #jasmine_content { position: fixed; right: 100%; }
10
+ .html-reporter .version { color: #aaaaaa; }
11
+ .html-reporter .banner { margin-top: 14px; }
12
+ .html-reporter .duration { color: #aaaaaa; float: right; }
13
+ .html-reporter .symbol-summary { overflow: hidden; *zoom: 1; margin: 14px 0; }
14
+ .html-reporter .symbol-summary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
15
+ .html-reporter .symbol-summary li.passed { font-size: 14px; }
16
+ .html-reporter .symbol-summary li.passed:before { color: #5e7d00; content: "\02022"; }
17
+ .html-reporter .symbol-summary li.failed { line-height: 9px; }
18
+ .html-reporter .symbol-summary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
19
+ .html-reporter .symbol-summary li.disabled { font-size: 14px; }
20
+ .html-reporter .symbol-summary li.disabled:before { color: #bababa; content: "\02022"; }
21
+ .html-reporter .symbol-summary li.pending { line-height: 17px; }
22
+ .html-reporter .symbol-summary li.pending:before { color: #ba9d37; content: "*"; }
23
+ .html-reporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
24
+ .html-reporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
25
+ .html-reporter .bar.failed { background-color: #b03911; }
26
+ .html-reporter .bar.passed { background-color: #a6b779; }
27
+ .html-reporter .bar.skipped { background-color: #bababa; }
28
+ .html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
29
+ .html-reporter .bar.menu a { color: #333333; }
30
+ .html-reporter .bar a { color: white; }
31
+ .html-reporter.spec-list .bar.menu.failure-list, .html-reporter.spec-list .results .failures { display: none; }
32
+ .html-reporter.failure-list .bar.menu.spec-list, .html-reporter.failure-list .summary { display: none; }
33
+ .html-reporter .running-alert { background-color: #666666; }
34
+ .html-reporter .results { margin-top: 14px; }
35
+ .html-reporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36
+ .html-reporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37
+ .html-reporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38
+ .html-reporter.showDetails .summary { display: none; }
39
+ .html-reporter.showDetails #details { display: block; }
40
+ .html-reporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41
+ .html-reporter .summary { margin-top: 14px; }
42
+ .html-reporter .summary ul { list-style-type: none; margin-left: 14px; padding-top: 0; padding-left: 0; }
43
+ .html-reporter .summary ul.suite { margin-top: 7px; margin-bottom: 7px; }
44
+ .html-reporter .summary li.passed a { color: #5e7d00; }
45
+ .html-reporter .summary li.failed a { color: #b03911; }
46
+ .html-reporter .summary li.pending a { color: #ba9d37; }
47
+ .html-reporter .description + .suite { margin-top: 0; }
48
+ .html-reporter .suite { margin-top: 14px; }
49
+ .html-reporter .suite a { color: #333333; }
50
+ .html-reporter .failures .spec-detail { margin-bottom: 28px; }
51
+ .html-reporter .failures .spec-detail .description { display: block; color: white; background-color: #b03911; }
52
+ .html-reporter .result-message { padding-top: 14px; color: #333333; white-space: pre; }
53
+ .html-reporter .result-message span.result { display: block; }
54
+ .html-reporter .stack-trace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #dddddd; background: white; white-space: pre; }
@@ -1,2600 +1,2361 @@
1
- var isCommonJS = typeof window == "undefined" && typeof exports == "object";
2
-
3
- /**
4
- * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
5
- *
6
- * @namespace
7
- */
8
- var jasmine = {};
9
- if (isCommonJS) exports.jasmine = jasmine;
10
- /**
11
- * @private
12
- */
13
- jasmine.unimplementedMethod_ = function() {
14
- throw new Error("unimplemented method");
15
- };
1
+ /*
2
+ Copyright (c) 2008-2013 Pivotal Labs
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining
5
+ a copy of this software and associated documentation files (the
6
+ "Software"), to deal in the Software without restriction, including
7
+ without limitation the rights to use, copy, modify, merge, publish,
8
+ distribute, sublicense, and/or sell copies of the Software, and to
9
+ permit persons to whom the Software is furnished to do so, subject to
10
+ the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be
13
+ included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ */
23
+ function getJasmineRequireObj() {
24
+ if (typeof module !== "undefined" && module.exports) {
25
+ return exports;
26
+ } else {
27
+ window.jasmineRequire = window.jasmineRequire || {};
28
+ return window.jasmineRequire;
29
+ }
30
+ }
31
+
32
+ getJasmineRequireObj().core = function(jRequire) {
33
+ j$ = {};
34
+
35
+ jRequire.base(j$);
36
+ j$.util = jRequire.util();
37
+ j$.Any = jRequire.Any();
38
+ j$.CallTracker = jRequire.CallTracker();
39
+ j$.Clock = jRequire.Clock();
40
+ j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
41
+ j$.Env = jRequire.Env(j$);
42
+ j$.ExceptionFormatter = jRequire.ExceptionFormatter();
43
+ j$.Expectation = jRequire.Expectation();
44
+ j$.buildExpectationResult = jRequire.buildExpectationResult();
45
+ j$.JsApiReporter = jRequire.JsApiReporter();
46
+ j$.matchersUtil = jRequire.matchersUtil(j$);
47
+ j$.ObjectContaining = jRequire.ObjectContaining(j$);
48
+ j$.pp = jRequire.pp(j$);
49
+ j$.QueueRunner = jRequire.QueueRunner();
50
+ j$.ReportDispatcher = jRequire.ReportDispatcher();
51
+ j$.Spec = jRequire.Spec();
52
+ j$.SpyStrategy = jRequire.SpyStrategy();
53
+ j$.Suite = jRequire.Suite();
54
+ j$.Timer = jRequire.Timer();
55
+ j$.version = jRequire.version();
56
+
57
+ j$.matchers = jRequire.requireMatchers(jRequire, j$);
58
+
59
+ return j$;
60
+ };
61
+
62
+ getJasmineRequireObj().requireMatchers = function(jRequire, j$) {
63
+ var availableMatchers = [
64
+ "toBe",
65
+ "toBeCloseTo",
66
+ "toBeDefined",
67
+ "toBeFalsy",
68
+ "toBeGreaterThan",
69
+ "toBeLessThan",
70
+ "toBeNaN",
71
+ "toBeNull",
72
+ "toBeTruthy",
73
+ "toBeUndefined",
74
+ "toContain",
75
+ "toEqual",
76
+ "toHaveBeenCalled",
77
+ "toHaveBeenCalledWith",
78
+ "toMatch",
79
+ "toThrow",
80
+ "toThrowError"
81
+ ],
82
+ matchers = {};
83
+
84
+ for (var i = 0; i < availableMatchers.length; i++) {
85
+ var name = availableMatchers[i];
86
+ matchers[name] = jRequire[name](j$);
87
+ }
88
+
89
+ return matchers;
90
+ };
91
+
92
+ getJasmineRequireObj().base = function(j$) {
93
+ j$.unimplementedMethod_ = function() {
94
+ throw new Error("unimplemented method");
95
+ };
16
96
 
17
- /**
18
- * Use <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> is just
19
- * a plain old variable and may be redefined by somebody else.
20
- *
21
- * @private
22
- */
23
- jasmine.undefined = jasmine.___undefined___;
24
-
25
- /**
26
- * Show diagnostic messages in the console if set to true
27
- *
28
- */
29
- jasmine.VERBOSE = false;
30
-
31
- /**
32
- * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed.
33
- *
34
- */
35
- jasmine.DEFAULT_UPDATE_INTERVAL = 250;
36
-
37
- /**
38
- * Maximum levels of nesting that will be included when an object is pretty-printed
39
- */
40
- jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
41
-
42
- /**
43
- * Default timeout interval in milliseconds for waitsFor() blocks.
44
- */
45
- jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
46
-
47
- /**
48
- * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
49
- * Set to false to let the exception bubble up in the browser.
50
- *
51
- */
52
- jasmine.CATCH_EXCEPTIONS = true;
53
-
54
- jasmine.getGlobal = function() {
55
- function getGlobal() {
56
- return this;
57
- }
97
+ j$.DEFAULT_UPDATE_INTERVAL = 250;
98
+ j$.MAX_PRETTY_PRINT_DEPTH = 40;
99
+ j$.DEFAULT_TIMEOUT_INTERVAL = 5000;
100
+
101
+ j$.getGlobal = function() {
102
+ function getGlobal() {
103
+ return this;
104
+ }
105
+
106
+ return getGlobal();
107
+ };
108
+
109
+ j$.getEnv = function(options) {
110
+ var env = j$.currentEnv_ = j$.currentEnv_ || new j$.Env(options);
111
+ //jasmine. singletons in here (setTimeout blah blah).
112
+ return env;
113
+ };
114
+
115
+ j$.isArray_ = function(value) {
116
+ return j$.isA_("Array", value);
117
+ };
118
+
119
+ j$.isString_ = function(value) {
120
+ return j$.isA_("String", value);
121
+ };
122
+
123
+ j$.isNumber_ = function(value) {
124
+ return j$.isA_("Number", value);
125
+ };
126
+
127
+ j$.isA_ = function(typeName, value) {
128
+ return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
129
+ };
130
+
131
+ j$.isDomNode = function(obj) {
132
+ return obj.nodeType > 0;
133
+ };
58
134
 
59
- return getGlobal();
135
+ j$.any = function(clazz) {
136
+ return new j$.Any(clazz);
137
+ };
138
+
139
+ j$.objectContaining = function(sample) {
140
+ return new j$.ObjectContaining(sample);
141
+ };
142
+
143
+ j$.createSpy = function(name, originalFn) {
144
+
145
+ var spyStrategy = new j$.SpyStrategy({
146
+ name: name,
147
+ fn: originalFn,
148
+ getSpy: function() { return spy; }
149
+ }),
150
+ callTracker = new j$.CallTracker(),
151
+ spy = function() {
152
+ callTracker.track({
153
+ object: this,
154
+ args: Array.prototype.slice.apply(arguments)
155
+ });
156
+ return spyStrategy.exec.apply(this, arguments);
157
+ };
158
+
159
+ for (var prop in originalFn) {
160
+ if (prop === 'and' || prop === 'calls') {
161
+ throw new Error("Jasmine spies would overwrite the 'and' and 'calls' properties on the object being spied upon");
162
+ }
163
+
164
+ spy[prop] = originalFn[prop];
165
+ }
166
+
167
+ spy.and = spyStrategy;
168
+ spy.calls = callTracker;
169
+
170
+ return spy;
171
+ };
172
+
173
+ j$.isSpy = function(putativeSpy) {
174
+ if (!putativeSpy) {
175
+ return false;
176
+ }
177
+ return putativeSpy.and instanceof j$.SpyStrategy &&
178
+ putativeSpy.calls instanceof j$.CallTracker;
179
+ };
180
+
181
+ j$.createSpyObj = function(baseName, methodNames) {
182
+ if (!j$.isArray_(methodNames) || methodNames.length === 0) {
183
+ throw "createSpyObj requires a non-empty array of method names to create spies for";
184
+ }
185
+ var obj = {};
186
+ for (var i = 0; i < methodNames.length; i++) {
187
+ obj[methodNames[i]] = j$.createSpy(baseName + '.' + methodNames[i]);
188
+ }
189
+ return obj;
190
+ };
60
191
  };
61
192
 
62
- /**
63
- * Allows for bound functions to be compared. Internal use only.
64
- *
65
- * @ignore
66
- * @private
67
- * @param base {Object} bound 'this' for the function
68
- * @param name {Function} function to find
69
- */
70
- jasmine.bindOriginal_ = function(base, name) {
71
- var original = base[name];
72
- if (original.apply) {
73
- return function() {
74
- return original.apply(base, arguments);
193
+ getJasmineRequireObj().util = function() {
194
+
195
+ var util = {};
196
+
197
+ util.inherit = function(childClass, parentClass) {
198
+ var subclass = function() {
75
199
  };
76
- } else {
77
- // IE support
78
- return jasmine.getGlobal()[name];
79
- }
80
- };
200
+ subclass.prototype = parentClass.prototype;
201
+ childClass.prototype = new subclass();
202
+ };
81
203
 
82
- jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout');
83
- jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout');
84
- jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval');
85
- jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval');
204
+ util.htmlEscape = function(str) {
205
+ if (!str) return str;
206
+ return str.replace(/&/g, '&amp;')
207
+ .replace(/</g, '&lt;')
208
+ .replace(/>/g, '&gt;');
209
+ };
86
210
 
87
- jasmine.MessageResult = function(values) {
88
- this.type = 'log';
89
- this.values = values;
90
- this.trace = new Error(); // todo: test better
91
- };
211
+ util.argsToArray = function(args) {
212
+ var arrayOfArgs = [];
213
+ for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
214
+ return arrayOfArgs;
215
+ };
92
216
 
93
- jasmine.MessageResult.prototype.toString = function() {
94
- var text = "";
95
- for (var i = 0; i < this.values.length; i++) {
96
- if (i > 0) text += " ";
97
- if (jasmine.isString_(this.values[i])) {
98
- text += this.values[i];
99
- } else {
100
- text += jasmine.pp(this.values[i]);
217
+ util.isUndefined = function(obj) {
218
+ return obj === void 0;
219
+ };
220
+
221
+ return util;
222
+ };
223
+
224
+ getJasmineRequireObj().Spec = function() {
225
+ function Spec(attrs) {
226
+ this.encounteredExpectations = false;
227
+ this.expectationFactory = attrs.expectationFactory;
228
+ this.resultCallback = attrs.resultCallback || function() {};
229
+ this.id = attrs.id;
230
+ this.description = attrs.description || '';
231
+ this.fn = attrs.fn;
232
+ this.beforeFns = attrs.beforeFns || function() {};
233
+ this.afterFns = attrs.afterFns || function() {};
234
+ this.catchingExceptions = attrs.catchingExceptions;
235
+ this.onStart = attrs.onStart || function() {};
236
+ this.exceptionFormatter = attrs.exceptionFormatter || function() {};
237
+ this.getSpecName = attrs.getSpecName || function() { return ''; };
238
+ this.expectationResultFactory = attrs.expectationResultFactory || function() { };
239
+ this.queueRunner = attrs.queueRunner || function() {};
240
+ this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
241
+
242
+ this.timer = attrs.timer || {setTimeout: setTimeout, clearTimeout: clearTimeout};
243
+
244
+ if (!this.fn) {
245
+ this.pend();
101
246
  }
247
+
248
+ this.result = {
249
+ id: this.id,
250
+ description: this.description,
251
+ fullName: this.getFullName(),
252
+ status: this.status(),
253
+ failedExpectations: []
254
+ };
102
255
  }
103
- return text;
104
- };
105
256
 
106
- jasmine.ExpectationResult = function(params) {
107
- this.type = 'expect';
108
- this.matcherName = params.matcherName;
109
- this.passed_ = params.passed;
110
- this.expected = params.expected;
111
- this.actual = params.actual;
112
- this.message = this.passed_ ? 'Passed.' : params.message;
257
+ Spec.prototype.addExpectationResult = function(passed, data) {
258
+ this.encounteredExpectations = true;
259
+ if (passed) {
260
+ return;
261
+ }
262
+ this.result.failedExpectations.push(this.expectationResultFactory(data));
263
+ };
113
264
 
114
- var trace = (params.trace || new Error(this.message));
115
- this.trace = this.passed_ ? '' : trace;
116
- };
265
+ Spec.prototype.expect = function(actual) {
266
+ return this.expectationFactory(actual, this);
267
+ };
117
268
 
118
- jasmine.ExpectationResult.prototype.toString = function () {
119
- return this.message;
120
- };
269
+ Spec.prototype.execute = function(onComplete) {
270
+ var self = this;
121
271
 
122
- jasmine.ExpectationResult.prototype.passed = function () {
123
- return this.passed_;
124
- };
272
+ this.onStart(this);
125
273
 
126
- /**
127
- * Getter for the Jasmine environment. Ensures one gets created
128
- */
129
- jasmine.getEnv = function() {
130
- var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env();
131
- return env;
132
- };
274
+ if (this.markedPending || this.disabled) {
275
+ complete();
276
+ return;
277
+ }
133
278
 
134
- /**
135
- * @ignore
136
- * @private
137
- * @param value
138
- * @returns {Boolean}
139
- */
140
- jasmine.isArray_ = function(value) {
141
- return jasmine.isA_("Array", value);
142
- };
279
+ function timeoutable(fn) {
280
+ return function(done) {
281
+ var timeout = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
282
+ onException(new Error('timeout'));
283
+ done();
284
+ }, 10000]]);
143
285
 
144
- /**
145
- * @ignore
146
- * @private
147
- * @param value
148
- * @returns {Boolean}
149
- */
150
- jasmine.isString_ = function(value) {
151
- return jasmine.isA_("String", value);
152
- };
286
+ var callDone = function() {
287
+ Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeout]]);
288
+ done();
289
+ };
153
290
 
154
- /**
155
- * @ignore
156
- * @private
157
- * @param value
158
- * @returns {Boolean}
159
- */
160
- jasmine.isNumber_ = function(value) {
161
- return jasmine.isA_("Number", value);
162
- };
291
+ fn(callDone); //TODO: do we care about more than 1 arg?
292
+ };
293
+ }
163
294
 
164
- /**
165
- * @ignore
166
- * @private
167
- * @param {String} typeName
168
- * @param value
169
- * @returns {Boolean}
170
- */
171
- jasmine.isA_ = function(typeName, value) {
172
- return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
173
- };
295
+ var befores = this.beforeFns() || [],
296
+ afters = this.afterFns() || [],
297
+ thisOne = (this.fn.length) ? timeoutable(this.fn) : this.fn;
298
+ var allFns = befores.concat(thisOne).concat(afters);
174
299
 
175
- /**
176
- * Pretty printer for expecations. Takes any object and turns it into a human-readable string.
177
- *
178
- * @param value {Object} an object to be outputted
179
- * @returns {String}
180
- */
181
- jasmine.pp = function(value) {
182
- var stringPrettyPrinter = new jasmine.StringPrettyPrinter();
183
- stringPrettyPrinter.format(value);
184
- return stringPrettyPrinter.string;
185
- };
300
+ this.queueRunner({
301
+ fns: allFns,
302
+ onException: onException,
303
+ onComplete: complete
304
+ });
186
305
 
187
- /**
188
- * Returns true if the object is a DOM Node.
189
- *
190
- * @param {Object} obj object to check
191
- * @returns {Boolean}
192
- */
193
- jasmine.isDomNode = function(obj) {
194
- return obj.nodeType > 0;
195
- };
306
+ function onException(e) {
307
+ if (Spec.isPendingSpecException(e)) {
308
+ self.pend();
309
+ return;
310
+ }
196
311
 
197
- /**
198
- * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter.
199
- *
200
- * @example
201
- * // don't care about which function is passed in, as long as it's a function
202
- * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function));
203
- *
204
- * @param {Class} clazz
205
- * @returns matchable object of the type clazz
206
- */
207
- jasmine.any = function(clazz) {
208
- return new jasmine.Matchers.Any(clazz);
209
- };
312
+ self.addExpectationResult(false, {
313
+ matcherName: "",
314
+ passed: false,
315
+ expected: "",
316
+ actual: "",
317
+ error: e
318
+ });
319
+ }
210
320
 
211
- /**
212
- * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
213
- * attributes on the object.
214
- *
215
- * @example
216
- * // don't care about any other attributes than foo.
217
- * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
218
- *
219
- * @param sample {Object} sample
220
- * @returns matchable object for the sample
221
- */
222
- jasmine.objectContaining = function (sample) {
223
- return new jasmine.Matchers.ObjectContaining(sample);
224
- };
321
+ function complete() {
322
+ self.result.status = self.status();
323
+ self.resultCallback(self.result);
225
324
 
226
- /**
227
- * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
228
- *
229
- * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine
230
- * expectation syntax. Spies can be checked if they were called or not and what the calling params were.
231
- *
232
- * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs).
233
- *
234
- * Spies are torn down at the end of every spec.
235
- *
236
- * Note: Do <b>not</b> call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj.
237
- *
238
- * @example
239
- * // a stub
240
- * var myStub = jasmine.createSpy('myStub'); // can be used anywhere
241
- *
242
- * // spy example
243
- * var foo = {
244
- * not: function(bool) { return !bool; }
245
- * }
246
- *
247
- * // actual foo.not will not be called, execution stops
248
- * spyOn(foo, 'not');
249
-
250
- // foo.not spied upon, execution will continue to implementation
251
- * spyOn(foo, 'not').andCallThrough();
252
- *
253
- * // fake example
254
- * var foo = {
255
- * not: function(bool) { return !bool; }
256
- * }
257
- *
258
- * // foo.not(val) will return val
259
- * spyOn(foo, 'not').andCallFake(function(value) {return value;});
260
- *
261
- * // mock example
262
- * foo.not(7 == 7);
263
- * expect(foo.not).toHaveBeenCalled();
264
- * expect(foo.not).toHaveBeenCalledWith(true);
265
- *
266
- * @constructor
267
- * @see spyOn, jasmine.createSpy, jasmine.createSpyObj
268
- * @param {String} name
269
- */
270
- jasmine.Spy = function(name) {
271
- /**
272
- * The name of the spy, if provided.
273
- */
274
- this.identity = name || 'unknown';
275
- /**
276
- * Is this Object a spy?
277
- */
278
- this.isSpy = true;
279
- /**
280
- * The actual function this spy stubs.
281
- */
282
- this.plan = function() {
283
- };
284
- /**
285
- * Tracking of the most recent call to the spy.
286
- * @example
287
- * var mySpy = jasmine.createSpy('foo');
288
- * mySpy(1, 2);
289
- * mySpy.mostRecentCall.args = [1, 2];
290
- */
291
- this.mostRecentCall = {};
292
-
293
- /**
294
- * Holds arguments for each call to the spy, indexed by call count
295
- * @example
296
- * var mySpy = jasmine.createSpy('foo');
297
- * mySpy(1, 2);
298
- * mySpy(7, 8);
299
- * mySpy.mostRecentCall.args = [7, 8];
300
- * mySpy.argsForCall[0] = [1, 2];
301
- * mySpy.argsForCall[1] = [7, 8];
302
- */
303
- this.argsForCall = [];
304
- this.calls = [];
305
- };
325
+ if (onComplete) {
326
+ onComplete();
327
+ }
328
+ }
329
+ };
306
330
 
307
- /**
308
- * Tells a spy to call through to the actual implemenatation.
309
- *
310
- * @example
311
- * var foo = {
312
- * bar: function() { // do some stuff }
313
- * }
314
- *
315
- * // defining a spy on an existing property: foo.bar
316
- * spyOn(foo, 'bar').andCallThrough();
317
- */
318
- jasmine.Spy.prototype.andCallThrough = function() {
319
- this.plan = this.originalValue;
320
- return this;
321
- };
331
+ Spec.prototype.disable = function() {
332
+ this.disabled = true;
333
+ };
322
334
 
323
- /**
324
- * For setting the return value of a spy.
325
- *
326
- * @example
327
- * // defining a spy from scratch: foo() returns 'baz'
328
- * var foo = jasmine.createSpy('spy on foo').andReturn('baz');
329
- *
330
- * // defining a spy on an existing property: foo.bar() returns 'baz'
331
- * spyOn(foo, 'bar').andReturn('baz');
332
- *
333
- * @param {Object} value
334
- */
335
- jasmine.Spy.prototype.andReturn = function(value) {
336
- this.plan = function() {
337
- return value;
338
- };
339
- return this;
340
- };
335
+ Spec.prototype.pend = function() {
336
+ this.markedPending = true;
337
+ };
341
338
 
342
- /**
343
- * For throwing an exception when a spy is called.
344
- *
345
- * @example
346
- * // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
347
- * var foo = jasmine.createSpy('spy on foo').andThrow('baz');
348
- *
349
- * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
350
- * spyOn(foo, 'bar').andThrow('baz');
351
- *
352
- * @param {String} exceptionMsg
353
- */
354
- jasmine.Spy.prototype.andThrow = function(exceptionMsg) {
355
- this.plan = function() {
356
- throw exceptionMsg;
357
- };
358
- return this;
359
- };
339
+ Spec.prototype.status = function() {
340
+ if (this.disabled) {
341
+ return 'disabled';
342
+ }
360
343
 
361
- /**
362
- * Calls an alternate implementation when a spy is called.
363
- *
364
- * @example
365
- * var baz = function() {
366
- * // do some stuff, return something
367
- * }
368
- * // defining a spy from scratch: foo() calls the function baz
369
- * var foo = jasmine.createSpy('spy on foo').andCall(baz);
370
- *
371
- * // defining a spy on an existing property: foo.bar() calls an anonymnous function
372
- * spyOn(foo, 'bar').andCall(function() { return 'baz';} );
373
- *
374
- * @param {Function} fakeFunc
375
- */
376
- jasmine.Spy.prototype.andCallFake = function(fakeFunc) {
377
- this.plan = fakeFunc;
378
- return this;
379
- };
344
+ if (this.markedPending || !this.encounteredExpectations) {
345
+ return 'pending';
346
+ }
380
347
 
381
- /**
382
- * Resets all of a spy's the tracking variables so that it can be used again.
383
- *
384
- * @example
385
- * spyOn(foo, 'bar');
386
- *
387
- * foo.bar();
388
- *
389
- * expect(foo.bar.callCount).toEqual(1);
390
- *
391
- * foo.bar.reset();
392
- *
393
- * expect(foo.bar.callCount).toEqual(0);
394
- */
395
- jasmine.Spy.prototype.reset = function() {
396
- this.wasCalled = false;
397
- this.callCount = 0;
398
- this.argsForCall = [];
399
- this.calls = [];
400
- this.mostRecentCall = {};
401
- };
348
+ if (this.result.failedExpectations.length > 0) {
349
+ return 'failed';
350
+ } else {
351
+ return 'passed';
352
+ }
353
+ };
402
354
 
403
- jasmine.createSpy = function(name) {
355
+ Spec.prototype.getFullName = function() {
356
+ return this.getSpecName(this);
357
+ };
358
+
359
+ Spec.pendingSpecExceptionMessage = "=> marked Pending";
404
360
 
405
- var spyObj = function() {
406
- spyObj.wasCalled = true;
407
- spyObj.callCount++;
408
- var args = jasmine.util.argsToArray(arguments);
409
- spyObj.mostRecentCall.object = this;
410
- spyObj.mostRecentCall.args = args;
411
- spyObj.argsForCall.push(args);
412
- spyObj.calls.push({object: this, args: args});
413
- return spyObj.plan.apply(this, arguments);
361
+ Spec.isPendingSpecException = function(e) {
362
+ return e.toString().indexOf(Spec.pendingSpecExceptionMessage) !== -1;
414
363
  };
415
364
 
416
- var spy = new jasmine.Spy(name);
365
+ return Spec;
366
+ };
417
367
 
418
- for (var prop in spy) {
419
- spyObj[prop] = spy[prop];
420
- }
368
+ if (typeof window == void 0 && typeof exports == "object") {
369
+ exports.Spec = jasmineRequire.Spec;
370
+ }
421
371
 
422
- spyObj.reset();
372
+ getJasmineRequireObj().Env = function(j$) {
373
+ function Env(options) {
374
+ options = options || {};
423
375
 
424
- return spyObj;
425
- };
376
+ var self = this;
377
+ var global = options.global || j$.getGlobal();
426
378
 
427
- /**
428
- * Determines whether an object is a spy.
429
- *
430
- * @param {jasmine.Spy|Object} putativeSpy
431
- * @returns {Boolean}
432
- */
433
- jasmine.isSpy = function(putativeSpy) {
434
- return putativeSpy && putativeSpy.isSpy;
435
- };
379
+ var catchExceptions = true;
436
380
 
437
- /**
438
- * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something
439
- * large in one call.
440
- *
441
- * @param {String} baseName name of spy class
442
- * @param {Array} methodNames array of names of methods to make spies
443
- */
444
- jasmine.createSpyObj = function(baseName, methodNames) {
445
- if (!jasmine.isArray_(methodNames) || methodNames.length === 0) {
446
- throw new Error('createSpyObj requires a non-empty array of method names to create spies for');
447
- }
448
- var obj = {};
449
- for (var i = 0; i < methodNames.length; i++) {
450
- obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]);
451
- }
452
- return obj;
453
- };
381
+ var realSetTimeout = j$.getGlobal().setTimeout;
382
+ var realClearTimeout = j$.getGlobal().clearTimeout;
383
+ this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler());
454
384
 
455
- /**
456
- * All parameters are pretty-printed and concatenated together, then written to the current spec's output.
457
- *
458
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
459
- */
460
- jasmine.log = function() {
461
- var spec = jasmine.getEnv().currentSpec;
462
- spec.log.apply(spec, arguments);
463
- };
385
+ var spies = [];
464
386
 
465
- /**
466
- * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy.
467
- *
468
- * @example
469
- * // spy example
470
- * var foo = {
471
- * not: function(bool) { return !bool; }
472
- * }
473
- * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops
474
- *
475
- * @see jasmine.createSpy
476
- * @param obj
477
- * @param methodName
478
- * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
479
- */
480
- var spyOn = function(obj, methodName) {
481
- return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
482
- };
483
- if (isCommonJS) exports.spyOn = spyOn;
484
-
485
- /**
486
- * Creates a Jasmine spec that will be added to the current suite.
487
- *
488
- * // TODO: pending tests
489
- *
490
- * @example
491
- * it('should be true', function() {
492
- * expect(true).toEqual(true);
493
- * });
494
- *
495
- * @param {String} desc description of this specification
496
- * @param {Function} func defines the preconditions and expectations of the spec
497
- */
498
- var it = function(desc, func) {
499
- return jasmine.getEnv().it(desc, func);
500
- };
501
- if (isCommonJS) exports.it = it;
502
-
503
- /**
504
- * Creates a <em>disabled</em> Jasmine spec.
505
- *
506
- * A convenience method that allows existing specs to be disabled temporarily during development.
507
- *
508
- * @param {String} desc description of this specification
509
- * @param {Function} func defines the preconditions and expectations of the spec
510
- */
511
- var xit = function(desc, func) {
512
- return jasmine.getEnv().xit(desc, func);
513
- };
514
- if (isCommonJS) exports.xit = xit;
515
-
516
- /**
517
- * Starts a chain for a Jasmine expectation.
518
- *
519
- * It is passed an Object that is the actual value and should chain to one of the many
520
- * jasmine.Matchers functions.
521
- *
522
- * @param {Object} actual Actual value to test against and expected value
523
- * @return {jasmine.Matchers}
524
- */
525
- var expect = function(actual) {
526
- return jasmine.getEnv().currentSpec.expect(actual);
527
- };
528
- if (isCommonJS) exports.expect = expect;
529
-
530
- /**
531
- * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs.
532
- *
533
- * @param {Function} func Function that defines part of a jasmine spec.
534
- */
535
- var runs = function(func) {
536
- jasmine.getEnv().currentSpec.runs(func);
537
- };
538
- if (isCommonJS) exports.runs = runs;
539
-
540
- /**
541
- * Waits a fixed time period before moving to the next block.
542
- *
543
- * @deprecated Use waitsFor() instead
544
- * @param {Number} timeout milliseconds to wait
545
- */
546
- var waits = function(timeout) {
547
- jasmine.getEnv().currentSpec.waits(timeout);
548
- };
549
- if (isCommonJS) exports.waits = waits;
550
-
551
- /**
552
- * Waits for the latchFunction to return true before proceeding to the next block.
553
- *
554
- * @param {Function} latchFunction
555
- * @param {String} optional_timeoutMessage
556
- * @param {Number} optional_timeout
557
- */
558
- var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
559
- jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments);
560
- };
561
- if (isCommonJS) exports.waitsFor = waitsFor;
562
-
563
- /**
564
- * A function that is called before each spec in a suite.
565
- *
566
- * Used for spec setup, including validating assumptions.
567
- *
568
- * @param {Function} beforeEachFunction
569
- */
570
- var beforeEach = function(beforeEachFunction) {
571
- jasmine.getEnv().beforeEach(beforeEachFunction);
572
- };
573
- if (isCommonJS) exports.beforeEach = beforeEach;
574
-
575
- /**
576
- * A function that is called after each spec in a suite.
577
- *
578
- * Used for restoring any state that is hijacked during spec execution.
579
- *
580
- * @param {Function} afterEachFunction
581
- */
582
- var afterEach = function(afterEachFunction) {
583
- jasmine.getEnv().afterEach(afterEachFunction);
584
- };
585
- if (isCommonJS) exports.afterEach = afterEach;
586
-
587
- /**
588
- * Defines a suite of specifications.
589
- *
590
- * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared
591
- * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization
592
- * of setup in some tests.
593
- *
594
- * @example
595
- * // TODO: a simple suite
596
- *
597
- * // TODO: a simple suite with a nested describe block
598
- *
599
- * @param {String} description A string, usually the class under test.
600
- * @param {Function} specDefinitions function that defines several specs.
601
- */
602
- var describe = function(description, specDefinitions) {
603
- return jasmine.getEnv().describe(description, specDefinitions);
604
- };
605
- if (isCommonJS) exports.describe = describe;
606
-
607
- /**
608
- * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development.
609
- *
610
- * @param {String} description A string, usually the class under test.
611
- * @param {Function} specDefinitions function that defines several specs.
612
- */
613
- var xdescribe = function(description, specDefinitions) {
614
- return jasmine.getEnv().xdescribe(description, specDefinitions);
615
- };
616
- if (isCommonJS) exports.xdescribe = xdescribe;
387
+ this.currentSpec = null;
617
388
 
389
+ this.reporter = new j$.ReportDispatcher([
390
+ "jasmineStarted",
391
+ "jasmineDone",
392
+ "suiteStarted",
393
+ "suiteDone",
394
+ "specStarted",
395
+ "specDone"
396
+ ]);
618
397
 
619
- // Provide the XMLHttpRequest class for IE 5.x-6.x:
620
- jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() {
621
- function tryIt(f) {
622
- try {
623
- return f();
624
- } catch(e) {
398
+ this.lastUpdate = 0;
399
+ this.specFilter = function() {
400
+ return true;
401
+ };
402
+
403
+ this.nextSpecId_ = 0;
404
+ this.nextSuiteId_ = 0;
405
+ this.equalityTesters_ = [];
406
+
407
+ var customEqualityTesters = [];
408
+ this.addCustomEqualityTester = function(tester) {
409
+ customEqualityTesters.push(tester);
410
+ };
411
+
412
+ j$.Expectation.addCoreMatchers(j$.matchers);
413
+
414
+ var expectationFactory = function(actual, spec) {
415
+ return j$.Expectation.Factory({
416
+ util: j$.matchersUtil,
417
+ customEqualityTesters: customEqualityTesters,
418
+ actual: actual,
419
+ addExpectationResult: addExpectationResult
420
+ });
421
+
422
+ function addExpectationResult(passed, result) {
423
+ return spec.addExpectationResult(passed, result);
424
+ }
425
+ };
426
+
427
+ var specStarted = function(spec) {
428
+ self.currentSpec = spec;
429
+ self.reporter.specStarted(spec.result);
430
+ };
431
+
432
+ var beforeFns = function(currentSuite) {
433
+ return function() {
434
+ var befores = [];
435
+ for (var suite = currentSuite; suite; suite = suite.parentSuite) {
436
+ befores = befores.concat(suite.beforeFns);
437
+ }
438
+ return befores.reverse();
439
+ };
440
+ };
441
+
442
+ var afterFns = function(currentSuite) {
443
+ return function() {
444
+ var afters = [];
445
+ for (var suite = currentSuite; suite; suite = suite.parentSuite) {
446
+ afters = afters.concat(suite.afterFns);
447
+ }
448
+ return afters;
449
+ };
450
+ };
451
+
452
+ var getSpecName = function(spec, currentSuite) {
453
+ return currentSuite.getFullName() + ' ' + spec.description + '.';
454
+ };
455
+
456
+ // TODO: we may just be able to pass in the fn instead of wrapping here
457
+ var buildExpectationResult = j$.buildExpectationResult,
458
+ exceptionFormatter = new j$.ExceptionFormatter(),
459
+ expectationResultFactory = function(attrs) {
460
+ attrs.messageFormatter = exceptionFormatter.message;
461
+ attrs.stackFormatter = exceptionFormatter.stack;
462
+
463
+ return buildExpectationResult(attrs);
464
+ };
465
+
466
+ // TODO: fix this naming, and here's where the value comes in
467
+ this.catchExceptions = function(value) {
468
+ catchExceptions = !!value;
469
+ return catchExceptions;
470
+ };
471
+
472
+ this.catchingExceptions = function() {
473
+ return catchExceptions;
474
+ };
475
+
476
+ this.catchException = function(e) {
477
+ return j$.Spec.isPendingSpecException(e) || catchExceptions;
478
+ };
479
+
480
+ var maximumSpecCallbackDepth = 20;
481
+ var currentSpecCallbackDepth = 0;
482
+
483
+ function clearStack(fn) {
484
+ currentSpecCallbackDepth++;
485
+ if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
486
+ currentSpecCallbackDepth = 0;
487
+ realSetTimeout(fn, 0);
488
+ } else {
489
+ fn();
490
+ }
625
491
  }
626
- return null;
627
- }
628
492
 
629
- var xhr = tryIt(function() {
630
- return new ActiveXObject("Msxml2.XMLHTTP.6.0");
631
- }) ||
632
- tryIt(function() {
633
- return new ActiveXObject("Msxml2.XMLHTTP.3.0");
634
- }) ||
635
- tryIt(function() {
636
- return new ActiveXObject("Msxml2.XMLHTTP");
637
- }) ||
638
- tryIt(function() {
639
- return new ActiveXObject("Microsoft.XMLHTTP");
493
+ var queueRunnerFactory = function(options) {
494
+ options.catchException = self.catchException;
495
+ options.clearStack = options.clearStack || clearStack;
496
+
497
+ new j$.QueueRunner(options).run(options.fns, 0);
498
+ };
499
+
500
+ var totalSpecsDefined = 0;
501
+ this.specFactory = function(description, fn, suite) {
502
+ totalSpecsDefined++;
503
+
504
+ var spec = new j$.Spec({
505
+ id: self.nextSpecId(),
506
+ beforeFns: beforeFns(suite),
507
+ afterFns: afterFns(suite),
508
+ expectationFactory: expectationFactory,
509
+ exceptionFormatter: exceptionFormatter,
510
+ resultCallback: specResultCallback,
511
+ getSpecName: function(spec) {
512
+ return getSpecName(spec, suite);
513
+ },
514
+ onStart: specStarted,
515
+ description: description,
516
+ expectationResultFactory: expectationResultFactory,
517
+ queueRunner: queueRunnerFactory,
518
+ fn: fn,
519
+ timer: {setTimeout: realSetTimeout, clearTimeout: realClearTimeout}
520
+ });
521
+
522
+ if (!self.specFilter(spec)) {
523
+ spec.disable();
524
+ }
525
+
526
+ return spec;
527
+
528
+ function removeAllSpies() {
529
+ for (var i = 0; i < spies.length; i++) {
530
+ var spyEntry = spies[i];
531
+ spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
532
+ }
533
+ spies = [];
534
+ }
535
+
536
+ function specResultCallback(result) {
537
+ removeAllSpies();
538
+ j$.Expectation.resetMatchers();
539
+ customEqualityTesters.length = 0;
540
+ self.clock.uninstall();
541
+ self.currentSpec = null;
542
+ self.reporter.specDone(result);
543
+ }
544
+ };
545
+
546
+ var suiteStarted = function(suite) {
547
+ self.reporter.suiteStarted(suite.result);
548
+ };
549
+
550
+ var suiteConstructor = j$.Suite;
551
+
552
+ this.topSuite = new j$.Suite({
553
+ env: this,
554
+ id: this.nextSuiteId(),
555
+ description: 'Jasmine__TopLevel__Suite',
556
+ queueRunner: queueRunnerFactory,
557
+ completeCallback: function() {}, // TODO - hook this up
558
+ resultCallback: function() {} // TODO - hook this up
640
559
  });
560
+ this.currentSuite = this.topSuite;
561
+
562
+ this.suiteFactory = function(description) {
563
+ return new suiteConstructor({
564
+ env: self,
565
+ id: self.nextSuiteId(),
566
+ description: description,
567
+ parentSuite: self.currentSuite,
568
+ queueRunner: queueRunnerFactory,
569
+ onStart: suiteStarted,
570
+ resultCallback: function(attrs) {
571
+ self.reporter.suiteDone(attrs);
572
+ }
573
+ });
574
+ };
641
575
 
642
- if (!xhr) throw new Error("This browser does not support XMLHttpRequest.");
643
-
644
- return xhr;
645
- } : XMLHttpRequest;
646
- /**
647
- * @namespace
648
- */
649
- jasmine.util = {};
650
-
651
- /**
652
- * Declare that a child class inherit it's prototype from the parent class.
653
- *
654
- * @private
655
- * @param {Function} childClass
656
- * @param {Function} parentClass
657
- */
658
- jasmine.util.inherit = function(childClass, parentClass) {
659
- /**
660
- * @private
661
- */
662
- var subclass = function() {
663
- };
664
- subclass.prototype = parentClass.prototype;
665
- childClass.prototype = new subclass();
666
- };
576
+ this.execute = function() {
577
+ this.reporter.jasmineStarted({
578
+ totalSpecsDefined: totalSpecsDefined
579
+ });
580
+ this.topSuite.execute(self.reporter.jasmineDone);
581
+ };
667
582
 
668
- jasmine.util.formatException = function(e) {
669
- var lineNumber;
670
- if (e.line) {
671
- lineNumber = e.line;
672
- }
673
- else if (e.lineNumber) {
674
- lineNumber = e.lineNumber;
675
- }
583
+ this.spyOn = function(obj, methodName) {
584
+ if (j$.util.isUndefined(obj)) {
585
+ throw new Error("spyOn could not find an object to spy upon for " + methodName + "()");
586
+ }
676
587
 
677
- var file;
588
+ if (j$.util.isUndefined(obj[methodName])) {
589
+ throw new Error(methodName + '() method does not exist');
590
+ }
678
591
 
679
- if (e.sourceURL) {
680
- file = e.sourceURL;
681
- }
682
- else if (e.fileName) {
683
- file = e.fileName;
684
- }
592
+ if (obj[methodName] && j$.isSpy(obj[methodName])) {
593
+ //TODO?: should this return the current spy? Downside: may cause user confusion about spy state
594
+ throw new Error(methodName + ' has already been spied upon');
595
+ }
596
+
597
+ var spy = j$.createSpy(methodName, obj[methodName]);
598
+
599
+ spies.push({
600
+ spy: spy,
601
+ baseObj: obj,
602
+ methodName: methodName,
603
+ originalValue: obj[methodName]
604
+ });
685
605
 
686
- var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString();
606
+ obj[methodName] = spy;
687
607
 
688
- if (file && lineNumber) {
689
- message += ' in ' + file + ' (line ' + lineNumber + ')';
608
+ return spy;
609
+ };
690
610
  }
691
611
 
692
- return message;
693
- };
612
+ Env.prototype.addMatchers = function(matchersToAdd) {
613
+ j$.Expectation.addMatchers(matchersToAdd);
614
+ };
694
615
 
695
- jasmine.util.htmlEscape = function(str) {
696
- if (!str) return str;
697
- return str.replace(/&/g, '&amp;')
698
- .replace(/</g, '&lt;')
699
- .replace(/>/g, '&gt;');
700
- };
616
+ Env.prototype.version = function() {
617
+ return j$.version;
618
+ };
701
619
 
702
- jasmine.util.argsToArray = function(args) {
703
- var arrayOfArgs = [];
704
- for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]);
705
- return arrayOfArgs;
706
- };
620
+ Env.prototype.expect = function(actual) {
621
+ return this.currentSpec.expect(actual);
622
+ };
707
623
 
708
- jasmine.util.extend = function(destination, source) {
709
- for (var property in source) destination[property] = source[property];
710
- return destination;
711
- };
712
624
 
713
- /**
714
- * Environment for Jasmine
715
- *
716
- * @constructor
717
- */
718
- jasmine.Env = function() {
719
- this.currentSpec = null;
720
- this.currentSuite = null;
721
- this.currentRunner_ = new jasmine.Runner(this);
625
+ // TODO: move this to closure
626
+ Env.prototype.versionString = function() {
627
+ console.log("DEPRECATED == use j$.version");
628
+ return j$.version;
629
+ };
630
+
631
+ // TODO: move this to closure
632
+ Env.prototype.nextSpecId = function() {
633
+ return this.nextSpecId_++;
634
+ };
635
+
636
+ // TODO: move this to closure
637
+ Env.prototype.nextSuiteId = function() {
638
+ return this.nextSuiteId_++;
639
+ };
640
+
641
+ // TODO: move this to closure
642
+ Env.prototype.addReporter = function(reporter) {
643
+ this.reporter.addReporter(reporter);
644
+ };
645
+
646
+ // TODO: move this to closure
647
+ Env.prototype.describe = function(description, specDefinitions) {
648
+ var suite = this.suiteFactory(description);
649
+
650
+ var parentSuite = this.currentSuite;
651
+ parentSuite.addSuite(suite);
652
+ this.currentSuite = suite;
653
+
654
+ var declarationError = null;
655
+ try {
656
+ specDefinitions.call(suite);
657
+ } catch (e) {
658
+ declarationError = e;
659
+ }
660
+
661
+ if (declarationError) {
662
+ this.it("encountered a declaration exception", function() {
663
+ throw declarationError;
664
+ });
665
+ }
666
+
667
+ this.currentSuite = parentSuite;
668
+
669
+ return suite;
670
+ };
671
+
672
+ // TODO: move this to closure
673
+ Env.prototype.xdescribe = function(description, specDefinitions) {
674
+ var suite = this.describe(description, specDefinitions);
675
+ suite.disable();
676
+ return suite;
677
+ };
722
678
 
723
- this.reporter = new jasmine.MultiReporter();
679
+ // TODO: move this to closure
680
+ Env.prototype.it = function(description, fn) {
681
+ var spec = this.specFactory(description, fn, this.currentSuite);
682
+ this.currentSuite.addSpec(spec);
683
+ return spec;
684
+ };
724
685
 
725
- this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL;
726
- this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL;
727
- this.lastUpdate = 0;
728
- this.specFilter = function() {
729
- return true;
686
+ // TODO: move this to closure
687
+ Env.prototype.xit = function(description, fn) {
688
+ var spec = this.it(description, fn);
689
+ spec.pend();
690
+ return spec;
730
691
  };
731
692
 
732
- this.nextSpecId_ = 0;
733
- this.nextSuiteId_ = 0;
734
- this.equalityTesters_ = [];
693
+ // TODO: move this to closure
694
+ Env.prototype.beforeEach = function(beforeEachFunction) {
695
+ this.currentSuite.beforeEach(beforeEachFunction);
696
+ };
697
+
698
+ // TODO: move this to closure
699
+ Env.prototype.afterEach = function(afterEachFunction) {
700
+ this.currentSuite.afterEach(afterEachFunction);
701
+ };
702
+
703
+ // TODO: move this to closure
704
+ Env.prototype.pending = function() {
705
+ throw j$.Spec.pendingSpecExceptionMessage;
706
+ };
735
707
 
736
- // wrap matchers
737
- this.matchersClass = function() {
738
- jasmine.Matchers.apply(this, arguments);
708
+ // TODO: Still needed?
709
+ Env.prototype.currentRunner = function() {
710
+ return this.topSuite;
739
711
  };
740
- jasmine.util.inherit(this.matchersClass, jasmine.Matchers);
741
712
 
742
- jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass);
713
+ return Env;
743
714
  };
744
715
 
716
+ getJasmineRequireObj().JsApiReporter = function() {
745
717
 
746
- jasmine.Env.prototype.setTimeout = jasmine.setTimeout;
747
- jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout;
748
- jasmine.Env.prototype.setInterval = jasmine.setInterval;
749
- jasmine.Env.prototype.clearInterval = jasmine.clearInterval;
718
+ var noopTimer = {
719
+ start: function(){},
720
+ elapsed: function(){ return 0; }
721
+ };
722
+
723
+ function JsApiReporter(options) {
724
+ var timer = options.timer || noopTimer,
725
+ status = "loaded";
726
+
727
+ this.started = false;
728
+ this.finished = false;
729
+
730
+ this.jasmineStarted = function() {
731
+ this.started = true;
732
+ status = 'started';
733
+ timer.start();
734
+ };
735
+
736
+ var executionTime;
737
+
738
+ this.jasmineDone = function() {
739
+ this.finished = true;
740
+ executionTime = timer.elapsed();
741
+ status = 'done';
742
+ };
743
+
744
+ this.status = function() {
745
+ return status;
746
+ };
747
+
748
+ var suites = {};
749
+
750
+ this.suiteStarted = function(result) {
751
+ storeSuite(result);
752
+ };
753
+
754
+ this.suiteDone = function(result) {
755
+ storeSuite(result);
756
+ };
757
+
758
+ function storeSuite(result) {
759
+ suites[result.id] = result;
760
+ }
761
+
762
+ this.suites = function() {
763
+ return suites;
764
+ };
765
+
766
+ var specs = [];
767
+ this.specStarted = function(result) { };
768
+
769
+ this.specDone = function(result) {
770
+ specs.push(result);
771
+ };
772
+
773
+ this.specResults = function(index, length) {
774
+ return specs.slice(index, index + length);
775
+ };
776
+
777
+ this.specs = function() {
778
+ return specs;
779
+ };
780
+
781
+ this.executionTime = function() {
782
+ return executionTime;
783
+ };
750
784
 
751
- /**
752
- * @returns an object containing jasmine version build info, if set.
753
- */
754
- jasmine.Env.prototype.version = function () {
755
- if (jasmine.version_) {
756
- return jasmine.version_;
757
- } else {
758
- throw new Error('Version not set');
759
785
  }
786
+
787
+ return JsApiReporter;
760
788
  };
761
789
 
762
- /**
763
- * @returns string containing jasmine version build info, if set.
764
- */
765
- jasmine.Env.prototype.versionString = function() {
766
- if (!jasmine.version_) {
767
- return "version unknown";
768
- }
790
+ getJasmineRequireObj().Any = function() {
769
791
 
770
- var version = this.version();
771
- var versionString = version.major + "." + version.minor + "." + version.build;
772
- if (version.release_candidate) {
773
- versionString += ".rc" + version.release_candidate;
792
+ function Any(expectedObject) {
793
+ this.expectedObject = expectedObject;
774
794
  }
775
- versionString += " revision " + version.revision;
776
- return versionString;
777
- };
778
795
 
779
- /**
780
- * @returns a sequential integer starting at 0
781
- */
782
- jasmine.Env.prototype.nextSpecId = function () {
783
- return this.nextSpecId_++;
784
- };
796
+ Any.prototype.jasmineMatches = function(other) {
797
+ if (this.expectedObject == String) {
798
+ return typeof other == 'string' || other instanceof String;
799
+ }
785
800
 
786
- /**
787
- * @returns a sequential integer starting at 0
788
- */
789
- jasmine.Env.prototype.nextSuiteId = function () {
790
- return this.nextSuiteId_++;
791
- };
801
+ if (this.expectedObject == Number) {
802
+ return typeof other == 'number' || other instanceof Number;
803
+ }
792
804
 
793
- /**
794
- * Register a reporter to receive status updates from Jasmine.
795
- * @param {jasmine.Reporter} reporter An object which will receive status updates.
796
- */
797
- jasmine.Env.prototype.addReporter = function(reporter) {
798
- this.reporter.addReporter(reporter);
799
- };
805
+ if (this.expectedObject == Function) {
806
+ return typeof other == 'function' || other instanceof Function;
807
+ }
800
808
 
801
- jasmine.Env.prototype.execute = function() {
802
- this.currentRunner_.execute();
809
+ if (this.expectedObject == Object) {
810
+ return typeof other == 'object';
811
+ }
812
+
813
+ if (this.expectedObject == Boolean) {
814
+ return typeof other == 'boolean';
815
+ }
816
+
817
+ return other instanceof this.expectedObject;
818
+ };
819
+
820
+ Any.prototype.jasmineToString = function() {
821
+ return '<jasmine.any(' + this.expectedClass + ')>';
822
+ };
823
+
824
+ return Any;
803
825
  };
826
+ getJasmineRequireObj().CallTracker = function() {
804
827
 
805
- jasmine.Env.prototype.describe = function(description, specDefinitions) {
806
- var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite);
828
+ function CallTracker() {
829
+ var calls = [];
807
830
 
808
- var parentSuite = this.currentSuite;
809
- if (parentSuite) {
810
- parentSuite.add(suite);
811
- } else {
812
- this.currentRunner_.add(suite);
813
- }
831
+ this.track = function(context) {
832
+ calls.push(context);
833
+ };
814
834
 
815
- this.currentSuite = suite;
835
+ this.any = function() {
836
+ return !!calls.length;
837
+ };
816
838
 
817
- var declarationError = null;
818
- try {
819
- specDefinitions.call(suite);
820
- } catch(e) {
821
- declarationError = e;
822
- }
839
+ this.count = function() {
840
+ return calls.length;
841
+ };
823
842
 
824
- if (declarationError) {
825
- this.it("encountered a declaration exception", function() {
826
- throw declarationError;
827
- });
828
- }
843
+ this.argsFor = function(index) {
844
+ var call = calls[index];
845
+ return call ? call.args : [];
846
+ };
829
847
 
830
- this.currentSuite = parentSuite;
848
+ this.all = function() {
849
+ return calls;
850
+ };
831
851
 
832
- return suite;
833
- };
852
+ this.allArgs = function() {
853
+ var callArgs = [];
854
+ for(var i = 0; i < calls.length; i++){
855
+ callArgs.push(calls[i].args);
856
+ }
834
857
 
835
- jasmine.Env.prototype.beforeEach = function(beforeEachFunction) {
836
- if (this.currentSuite) {
837
- this.currentSuite.beforeEach(beforeEachFunction);
838
- } else {
839
- this.currentRunner_.beforeEach(beforeEachFunction);
840
- }
841
- };
858
+ return callArgs;
859
+ };
842
860
 
843
- jasmine.Env.prototype.currentRunner = function () {
844
- return this.currentRunner_;
845
- };
861
+ this.first = function() {
862
+ return calls[0];
863
+ };
846
864
 
847
- jasmine.Env.prototype.afterEach = function(afterEachFunction) {
848
- if (this.currentSuite) {
849
- this.currentSuite.afterEach(afterEachFunction);
850
- } else {
851
- this.currentRunner_.afterEach(afterEachFunction);
865
+ this.mostRecent = function() {
866
+ return calls[calls.length - 1];
867
+ };
868
+
869
+ this.reset = function() {
870
+ calls = [];
871
+ };
852
872
  }
853
873
 
854
- };
874
+ return CallTracker;
875
+ };
876
+
877
+ getJasmineRequireObj().Clock = function() {
878
+ function Clock(global, delayedFunctionScheduler) {
879
+ var self = this,
880
+ realTimingFunctions = {
881
+ setTimeout: global.setTimeout,
882
+ clearTimeout: global.clearTimeout,
883
+ setInterval: global.setInterval,
884
+ clearInterval: global.clearInterval
885
+ },
886
+ fakeTimingFunctions = {
887
+ setTimeout: setTimeout,
888
+ clearTimeout: clearTimeout,
889
+ setInterval: setInterval,
890
+ clearInterval: clearInterval
891
+ },
892
+ timer = realTimingFunctions,
893
+ installed = false;
894
+
895
+ self.install = function() {
896
+ installed = true;
897
+ timer = fakeTimingFunctions;
898
+ };
855
899
 
856
- jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) {
857
- return {
858
- execute: function() {
900
+ self.uninstall = function() {
901
+ delayedFunctionScheduler.reset();
902
+ installed = false;
903
+ timer = realTimingFunctions;
904
+ };
905
+
906
+ self.setTimeout = function(fn, delay, params) {
907
+ if (legacyIE()) {
908
+ if (arguments.length > 2) {
909
+ throw new Error("IE < 9 cannot support extra params to setTimeout without a polyfill");
910
+ }
911
+ return timer.setTimeout(fn, delay);
912
+ }
913
+ return Function.prototype.apply.apply(timer.setTimeout, [global, arguments]);
914
+ };
915
+
916
+ self.setInterval = function(fn, delay, params) {
917
+ if (legacyIE()) {
918
+ if (arguments.length > 2) {
919
+ throw new Error("IE < 9 cannot support extra params to setInterval without a polyfill");
920
+ }
921
+ return timer.setInterval(fn, delay);
922
+ }
923
+ return Function.prototype.apply.apply(timer.setInterval, [global, arguments]);
924
+ };
925
+
926
+ self.clearTimeout = function(id) {
927
+ return Function.prototype.call.apply(timer.clearTimeout, [global, id]);
928
+ };
929
+
930
+ self.clearInterval = function(id) {
931
+ return Function.prototype.call.apply(timer.clearInterval, [global, id]);
932
+ };
933
+
934
+ self.tick = function(millis) {
935
+ if (installed) {
936
+ delayedFunctionScheduler.tick(millis);
937
+ } else {
938
+ throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
939
+ }
940
+ };
941
+
942
+ return self;
943
+
944
+ function legacyIE() {
945
+ //if these methods are polyfilled, apply will be present
946
+ //TODO: it may be difficult to load the polyfill before jasmine loads
947
+ //(env should be new-ed inside of onload)
948
+ return !(global.setTimeout || global.setInterval).apply;
859
949
  }
860
- };
950
+
951
+ function setTimeout(fn, delay) {
952
+ return delayedFunctionScheduler.scheduleFunction(fn, delay, argSlice(arguments, 2));
953
+ }
954
+
955
+ function clearTimeout(id) {
956
+ return delayedFunctionScheduler.removeFunctionWithId(id);
957
+ }
958
+
959
+ function setInterval(fn, interval) {
960
+ return delayedFunctionScheduler.scheduleFunction(fn, interval, argSlice(arguments, 2), true);
961
+ }
962
+
963
+ function clearInterval(id) {
964
+ return delayedFunctionScheduler.removeFunctionWithId(id);
965
+ }
966
+
967
+ function argSlice(argsObj, n) {
968
+ return Array.prototype.slice.call(argsObj, 2);
969
+ }
970
+ }
971
+
972
+ return Clock;
861
973
  };
862
974
 
863
- jasmine.Env.prototype.it = function(description, func) {
864
- var spec = new jasmine.Spec(this, this.currentSuite, description);
865
- this.currentSuite.add(spec);
866
- this.currentSpec = spec;
975
+ getJasmineRequireObj().DelayedFunctionScheduler = function() {
976
+ function DelayedFunctionScheduler() {
977
+ var self = this;
978
+ var scheduledFunctions = {};
979
+ var currentTime = 0;
980
+ var delayedFnCount = 0;
981
+
982
+ self.tick = function(millis) {
983
+ millis = millis || 0;
984
+ runFunctionsWithinRange(currentTime, currentTime + millis);
985
+ currentTime = currentTime + millis;
986
+ };
987
+
988
+ self.scheduleFunction = function(funcToCall, millis, params, recurring, timeoutKey, runAtMillis) {
989
+ var f;
990
+ if (typeof(funcToCall) === 'string') {
991
+ /* jshint evil: true */
992
+ f = function() { return eval(funcToCall); };
993
+ /* jshint evil: false */
994
+ } else {
995
+ f = funcToCall;
996
+ }
997
+
998
+ millis = millis || 0;
999
+ timeoutKey = timeoutKey || ++delayedFnCount;
1000
+ runAtMillis = runAtMillis || (currentTime + millis);
1001
+ scheduledFunctions[timeoutKey] = {
1002
+ runAtMillis: runAtMillis,
1003
+ funcToCall: f,
1004
+ recurring: recurring,
1005
+ params: params,
1006
+ timeoutKey: timeoutKey,
1007
+ millis: millis
1008
+ };
1009
+ return timeoutKey;
1010
+ };
1011
+
1012
+ self.removeFunctionWithId = function(timeoutKey) {
1013
+ delete scheduledFunctions[timeoutKey];
1014
+ };
867
1015
 
868
- if (func) {
869
- spec.runs(func);
870
- }
1016
+ self.reset = function() {
1017
+ currentTime = 0;
1018
+ scheduledFunctions = {};
1019
+ delayedFnCount = 0;
1020
+ };
871
1021
 
872
- return spec;
873
- };
1022
+ return self;
1023
+
1024
+ // finds/dupes functions within range and removes them.
1025
+ function functionsWithinRange(startMillis, endMillis) {
1026
+ var fnsToRun = [];
1027
+ for (var timeoutKey in scheduledFunctions) {
1028
+ var scheduledFunc = scheduledFunctions[timeoutKey];
1029
+ if (scheduledFunc &&
1030
+ scheduledFunc.runAtMillis >= startMillis &&
1031
+ scheduledFunc.runAtMillis <= endMillis) {
1032
+
1033
+ // remove fn -- we'll reschedule later if it is recurring.
1034
+ self.removeFunctionWithId(timeoutKey);
1035
+ if (!scheduledFunc.recurring) {
1036
+ fnsToRun.push(scheduledFunc); // schedules each function only once
1037
+ } else {
1038
+ fnsToRun.push(buildNthInstanceOf(scheduledFunc, 0));
1039
+ var additionalTimesFnRunsInRange =
1040
+ Math.floor((endMillis - scheduledFunc.runAtMillis) / scheduledFunc.millis);
1041
+ for (var i = 0; i < additionalTimesFnRunsInRange; i++) {
1042
+ fnsToRun.push(buildNthInstanceOf(scheduledFunc, i + 1));
1043
+ }
1044
+ reschedule(buildNthInstanceOf(scheduledFunc, additionalTimesFnRunsInRange));
1045
+ }
1046
+ }
1047
+ }
874
1048
 
875
- jasmine.Env.prototype.xit = function(desc, func) {
876
- return {
877
- id: this.nextSpecId(),
878
- runs: function() {
1049
+ return fnsToRun;
879
1050
  }
880
- };
881
- };
882
-
883
- jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
884
- if (a.source != b.source)
885
- mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
886
1051
 
887
- if (a.ignoreCase != b.ignoreCase)
888
- mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
1052
+ function buildNthInstanceOf(scheduledFunc, n) {
1053
+ return {
1054
+ runAtMillis: scheduledFunc.runAtMillis + (scheduledFunc.millis * n),
1055
+ funcToCall: scheduledFunc.funcToCall,
1056
+ params: scheduledFunc.params,
1057
+ millis: scheduledFunc.millis,
1058
+ recurring: scheduledFunc.recurring,
1059
+ timeoutKey: scheduledFunc.timeoutKey
1060
+ };
1061
+ }
889
1062
 
890
- if (a.global != b.global)
891
- mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
1063
+ function reschedule(scheduledFn) {
1064
+ self.scheduleFunction(scheduledFn.funcToCall,
1065
+ scheduledFn.millis,
1066
+ scheduledFn.params,
1067
+ true,
1068
+ scheduledFn.timeoutKey,
1069
+ scheduledFn.runAtMillis + scheduledFn.millis);
1070
+ }
892
1071
 
893
- if (a.multiline != b.multiline)
894
- mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
895
1072
 
896
- if (a.sticky != b.sticky)
897
- mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
1073
+ function runFunctionsWithinRange(startMillis, endMillis) {
1074
+ var funcsToRun = functionsWithinRange(startMillis, endMillis);
1075
+ if (funcsToRun.length === 0) {
1076
+ return;
1077
+ }
898
1078
 
899
- return (mismatchValues.length === 0);
900
- };
1079
+ funcsToRun.sort(function(a, b) {
1080
+ return a.runAtMillis - b.runAtMillis;
1081
+ });
901
1082
 
902
- jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
903
- if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
904
- return true;
1083
+ for (var i = 0; i < funcsToRun.length; ++i) {
1084
+ var funcToRun = funcsToRun[i];
1085
+ funcToRun.funcToCall.apply(null, funcToRun.params || []);
1086
+ }
1087
+ }
905
1088
  }
906
1089
 
907
- a.__Jasmine_been_here_before__ = b;
908
- b.__Jasmine_been_here_before__ = a;
909
-
910
- var hasKey = function(obj, keyName) {
911
- return obj !== null && obj[keyName] !== jasmine.undefined;
912
- };
1090
+ return DelayedFunctionScheduler;
1091
+ };
913
1092
 
914
- for (var property in b) {
915
- if (!hasKey(a, property) && hasKey(b, property)) {
916
- mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
917
- }
918
- }
919
- for (property in a) {
920
- if (!hasKey(b, property) && hasKey(a, property)) {
921
- mismatchKeys.push("expected missing key '" + property + "', but present in actual.");
922
- }
923
- }
924
- for (property in b) {
925
- if (property == '__Jasmine_been_here_before__') continue;
926
- if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) {
927
- mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual.");
928
- }
929
- }
1093
+ getJasmineRequireObj().ExceptionFormatter = function() {
1094
+ function ExceptionFormatter() {
1095
+ this.message = function(error) {
1096
+ var message = error.name +
1097
+ ': ' +
1098
+ error.message;
930
1099
 
931
- if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) {
932
- mismatchValues.push("arrays were not the same length");
933
- }
1100
+ if (error.fileName || error.sourceURL) {
1101
+ message += " in " + (error.fileName || error.sourceURL);
1102
+ }
934
1103
 
935
- delete a.__Jasmine_been_here_before__;
936
- delete b.__Jasmine_been_here_before__;
937
- return (mismatchKeys.length === 0 && mismatchValues.length === 0);
938
- };
1104
+ if (error.line || error.lineNumber) {
1105
+ message += " (line " + (error.line || error.lineNumber) + ")";
1106
+ }
939
1107
 
940
- jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
941
- mismatchKeys = mismatchKeys || [];
942
- mismatchValues = mismatchValues || [];
1108
+ return message;
1109
+ };
943
1110
 
944
- for (var i = 0; i < this.equalityTesters_.length; i++) {
945
- var equalityTester = this.equalityTesters_[i];
946
- var result = equalityTester(a, b, this, mismatchKeys, mismatchValues);
947
- if (result !== jasmine.undefined) return result;
1111
+ this.stack = function(error) {
1112
+ return error ? error.stack : null;
1113
+ };
948
1114
  }
949
1115
 
950
- if (a === b) return true;
1116
+ return ExceptionFormatter;
1117
+ };
951
1118
 
952
- if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) {
953
- return (a == jasmine.undefined && b == jasmine.undefined);
954
- }
1119
+ getJasmineRequireObj().Expectation = function() {
955
1120
 
956
- if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) {
957
- return a === b;
958
- }
1121
+ var matchers = {};
959
1122
 
960
- if (a instanceof Date && b instanceof Date) {
961
- return a.getTime() == b.getTime();
962
- }
1123
+ function Expectation(options) {
1124
+ this.util = options.util || { buildFailureMessage: function() {} };
1125
+ this.customEqualityTesters = options.customEqualityTesters || [];
1126
+ this.actual = options.actual;
1127
+ this.addExpectationResult = options.addExpectationResult || function(){};
1128
+ this.isNot = options.isNot;
963
1129
 
964
- if (a.jasmineMatches) {
965
- return a.jasmineMatches(b);
1130
+ for (var matcherName in matchers) {
1131
+ this[matcherName] = matchers[matcherName];
1132
+ }
966
1133
  }
967
1134
 
968
- if (b.jasmineMatches) {
969
- return b.jasmineMatches(a);
970
- }
1135
+ Expectation.prototype.wrapCompare = function(name, matcherFactory) {
1136
+ return function() {
1137
+ var args = Array.prototype.slice.call(arguments, 0),
1138
+ expected = args.slice(0),
1139
+ message = "";
971
1140
 
972
- if (a instanceof jasmine.Matchers.ObjectContaining) {
973
- return a.matches(b);
974
- }
1141
+ args.unshift(this.actual);
975
1142
 
976
- if (b instanceof jasmine.Matchers.ObjectContaining) {
977
- return b.matches(a);
978
- }
1143
+ var result = matcherFactory(this.util, this.customEqualityTesters).compare.apply(null, args);
979
1144
 
980
- if (jasmine.isString_(a) && jasmine.isString_(b)) {
981
- return (a == b);
982
- }
1145
+ if (this.isNot) {
1146
+ result.pass = !result.pass;
1147
+ }
983
1148
 
984
- if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) {
985
- return (a == b);
986
- }
1149
+ if (!result.pass) {
1150
+ if (!result.message) {
1151
+ args.unshift(this.isNot);
1152
+ args.unshift(name);
1153
+ message = this.util.buildFailureMessage.apply(null, args);
1154
+ } else {
1155
+ message = result.message;
1156
+ }
1157
+ }
987
1158
 
988
- if (a instanceof RegExp && b instanceof RegExp) {
989
- return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
990
- }
1159
+ if (expected.length == 1) {
1160
+ expected = expected[0];
1161
+ }
991
1162
 
992
- if (typeof a === "object" && typeof b === "object") {
993
- return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
994
- }
1163
+ // TODO: how many of these params are needed?
1164
+ this.addExpectationResult(
1165
+ result.pass,
1166
+ {
1167
+ matcherName: name,
1168
+ passed: result.pass,
1169
+ message: message,
1170
+ actual: this.actual,
1171
+ expected: expected // TODO: this may need to be arrayified/sliced
1172
+ }
1173
+ );
1174
+ };
1175
+ };
995
1176
 
996
- //Straight check
997
- return (a === b);
998
- };
1177
+ Expectation.addCoreMatchers = function(matchers) {
1178
+ var prototype = Expectation.prototype;
1179
+ for (var matcherName in matchers) {
1180
+ var matcher = matchers[matcherName];
1181
+ prototype[matcherName] = prototype.wrapCompare(matcherName, matcher);
1182
+ }
1183
+ };
999
1184
 
1000
- jasmine.Env.prototype.contains_ = function(haystack, needle) {
1001
- if (jasmine.isArray_(haystack)) {
1002
- for (var i = 0; i < haystack.length; i++) {
1003
- if (this.equals_(haystack[i], needle)) return true;
1185
+ Expectation.addMatchers = function(matchersToAdd) {
1186
+ for (var name in matchersToAdd) {
1187
+ var matcher = matchersToAdd[name];
1188
+ matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
1004
1189
  }
1005
- return false;
1006
- }
1007
- return haystack.indexOf(needle) >= 0;
1008
- };
1190
+ };
1009
1191
 
1010
- jasmine.Env.prototype.addEqualityTester = function(equalityTester) {
1011
- this.equalityTesters_.push(equalityTester);
1012
- };
1013
- /** No-op base class for Jasmine reporters.
1014
- *
1015
- * @constructor
1016
- */
1017
- jasmine.Reporter = function() {
1018
- };
1192
+ Expectation.resetMatchers = function() {
1193
+ for (var name in matchers) {
1194
+ delete matchers[name];
1195
+ }
1196
+ };
1019
1197
 
1020
- //noinspection JSUnusedLocalSymbols
1021
- jasmine.Reporter.prototype.reportRunnerStarting = function(runner) {
1022
- };
1198
+ Expectation.Factory = function(options) {
1199
+ options = options || {};
1023
1200
 
1024
- //noinspection JSUnusedLocalSymbols
1025
- jasmine.Reporter.prototype.reportRunnerResults = function(runner) {
1026
- };
1201
+ var expect = new Expectation(options);
1027
1202
 
1028
- //noinspection JSUnusedLocalSymbols
1029
- jasmine.Reporter.prototype.reportSuiteResults = function(suite) {
1030
- };
1203
+ // TODO: this would be nice as its own Object - NegativeExpectation
1204
+ // TODO: copy instead of mutate options
1205
+ options.isNot = true;
1206
+ expect.not = new Expectation(options);
1031
1207
 
1032
- //noinspection JSUnusedLocalSymbols
1033
- jasmine.Reporter.prototype.reportSpecStarting = function(spec) {
1034
- };
1208
+ return expect;
1209
+ };
1035
1210
 
1036
- //noinspection JSUnusedLocalSymbols
1037
- jasmine.Reporter.prototype.reportSpecResults = function(spec) {
1211
+ return Expectation;
1038
1212
  };
1039
1213
 
1040
- //noinspection JSUnusedLocalSymbols
1041
- jasmine.Reporter.prototype.log = function(str) {
1042
- };
1214
+ //TODO: expectation result may make more sense as a presentation of an expectation.
1215
+ getJasmineRequireObj().buildExpectationResult = function() {
1216
+ function buildExpectationResult(options) {
1217
+ var messageFormatter = options.messageFormatter || function() {},
1218
+ stackFormatter = options.stackFormatter || function() {};
1043
1219
 
1044
- /**
1045
- * Blocks are functions with executable code that make up a spec.
1046
- *
1047
- * @constructor
1048
- * @param {jasmine.Env} env
1049
- * @param {Function} func
1050
- * @param {jasmine.Spec} spec
1051
- */
1052
- jasmine.Block = function(env, func, spec) {
1053
- this.env = env;
1054
- this.func = func;
1055
- this.spec = spec;
1056
- };
1220
+ return {
1221
+ matcherName: options.matcherName,
1222
+ expected: options.expected,
1223
+ actual: options.actual,
1224
+ message: message(),
1225
+ stack: stack(),
1226
+ passed: options.passed
1227
+ };
1057
1228
 
1058
- jasmine.Block.prototype.execute = function(onComplete) {
1059
- if (!jasmine.CATCH_EXCEPTIONS) {
1060
- this.func.apply(this.spec);
1061
- }
1062
- else {
1063
- try {
1064
- this.func.apply(this.spec);
1065
- } catch (e) {
1066
- this.spec.fail(e);
1229
+ function message() {
1230
+ if (options.passed) {
1231
+ return "Passed.";
1232
+ } else if (options.message) {
1233
+ return options.message;
1234
+ } else if (options.error) {
1235
+ return messageFormatter(options.error);
1236
+ }
1237
+ return "";
1067
1238
  }
1068
- }
1069
- onComplete();
1070
- };
1071
- /** JavaScript API reporter.
1072
- *
1073
- * @constructor
1074
- */
1075
- jasmine.JsApiReporter = function() {
1076
- this.started = false;
1077
- this.finished = false;
1078
- this.suites_ = [];
1079
- this.results_ = {};
1080
- };
1081
-
1082
- jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) {
1083
- this.started = true;
1084
- var suites = runner.topLevelSuites();
1085
- for (var i = 0; i < suites.length; i++) {
1086
- var suite = suites[i];
1087
- this.suites_.push(this.summarize_(suite));
1088
- }
1089
- };
1090
1239
 
1091
- jasmine.JsApiReporter.prototype.suites = function() {
1092
- return this.suites_;
1093
- };
1240
+ function stack() {
1241
+ if (options.passed) {
1242
+ return "";
1243
+ }
1094
1244
 
1095
- jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) {
1096
- var isSuite = suiteOrSpec instanceof jasmine.Suite;
1097
- var summary = {
1098
- id: suiteOrSpec.id,
1099
- name: suiteOrSpec.description,
1100
- type: isSuite ? 'suite' : 'spec',
1101
- children: []
1102
- };
1103
-
1104
- if (isSuite) {
1105
- var children = suiteOrSpec.children();
1106
- for (var i = 0; i < children.length; i++) {
1107
- summary.children.push(this.summarize_(children[i]));
1245
+ var error = options.error;
1246
+ if (!error) {
1247
+ try {
1248
+ throw new Error(message());
1249
+ } catch (e) {
1250
+ error = e;
1251
+ }
1252
+ }
1253
+ return stackFormatter(error);
1108
1254
  }
1109
1255
  }
1110
- return summary;
1111
- };
1112
-
1113
- jasmine.JsApiReporter.prototype.results = function() {
1114
- return this.results_;
1115
- };
1116
1256
 
1117
- jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) {
1118
- return this.results_[specId];
1257
+ return buildExpectationResult;
1119
1258
  };
1120
1259
 
1121
- //noinspection JSUnusedLocalSymbols
1122
- jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) {
1123
- this.finished = true;
1124
- };
1260
+ getJasmineRequireObj().ObjectContaining = function(j$) {
1125
1261
 
1126
- //noinspection JSUnusedLocalSymbols
1127
- jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) {
1128
- };
1262
+ function ObjectContaining(sample) {
1263
+ this.sample = sample;
1264
+ }
1129
1265
 
1130
- //noinspection JSUnusedLocalSymbols
1131
- jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) {
1132
- this.results_[spec.id] = {
1133
- messages: spec.results().getItems(),
1134
- result: spec.results().failedCount > 0 ? "failed" : "passed"
1135
- };
1136
- };
1266
+ ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1267
+ if (typeof(this.sample) !== "object") { throw new Error("You must provide an object to objectContaining, not '"+this.sample+"'."); }
1137
1268
 
1138
- //noinspection JSUnusedLocalSymbols
1139
- jasmine.JsApiReporter.prototype.log = function(str) {
1140
- };
1269
+ mismatchKeys = mismatchKeys || [];
1270
+ mismatchValues = mismatchValues || [];
1141
1271
 
1142
- jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){
1143
- var results = {};
1144
- for (var i = 0; i < specIds.length; i++) {
1145
- var specId = specIds[i];
1146
- results[specId] = this.summarizeResult_(this.results_[specId]);
1147
- }
1148
- return results;
1149
- };
1272
+ var hasKey = function(obj, keyName) {
1273
+ return obj !== null && !j$.util.isUndefined(obj[keyName]);
1274
+ };
1150
1275
 
1151
- jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){
1152
- var summaryMessages = [];
1153
- var messagesLength = result.messages.length;
1154
- for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
1155
- var resultMessage = result.messages[messageIndex];
1156
- summaryMessages.push({
1157
- text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined,
1158
- passed: resultMessage.passed ? resultMessage.passed() : true,
1159
- type: resultMessage.type,
1160
- message: resultMessage.message,
1161
- trace: {
1162
- stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
1276
+ for (var property in this.sample) {
1277
+ if (!hasKey(other, property) && hasKey(this.sample, property)) {
1278
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1163
1279
  }
1164
- });
1165
- }
1280
+ else if (!j$.matchersUtil.equals(this.sample[property], other[property])) {
1281
+ mismatchValues.push("'" + property + "' was '" + (other[property] ? j$.util.htmlEscape(other[property].toString()) : other[property]) + "' in actual, but was '" + (this.sample[property] ? j$.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in expected.");
1282
+ }
1283
+ }
1166
1284
 
1167
- return {
1168
- result : result.result,
1169
- messages : summaryMessages
1285
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1170
1286
  };
1171
- };
1172
1287
 
1173
- /**
1174
- * @constructor
1175
- * @param {jasmine.Env} env
1176
- * @param actual
1177
- * @param {jasmine.Spec} spec
1178
- */
1179
- jasmine.Matchers = function(env, actual, spec, opt_isNot) {
1180
- this.env = env;
1181
- this.actual = actual;
1182
- this.spec = spec;
1183
- this.isNot = opt_isNot || false;
1184
- this.reportWasCalled_ = false;
1185
- };
1288
+ ObjectContaining.prototype.jasmineToString = function() {
1289
+ return "<jasmine.objectContaining(" + j$.pp(this.sample) + ")>";
1290
+ };
1186
1291
 
1187
- // todo: @deprecated as of Jasmine 0.11, remove soon [xw]
1188
- jasmine.Matchers.pp = function(str) {
1189
- throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!");
1292
+ return ObjectContaining;
1190
1293
  };
1191
1294
 
1192
- // todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw]
1193
- jasmine.Matchers.prototype.report = function(result, failing_message, details) {
1194
- throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs");
1195
- };
1295
+ getJasmineRequireObj().pp = function(j$) {
1196
1296
 
1197
- jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) {
1198
- for (var methodName in prototype) {
1199
- if (methodName == 'report') continue;
1200
- var orig = prototype[methodName];
1201
- matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig);
1297
+ function PrettyPrinter() {
1298
+ this.ppNestLevel_ = 0;
1202
1299
  }
1203
- };
1204
-
1205
- jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) {
1206
- return function() {
1207
- var matcherArgs = jasmine.util.argsToArray(arguments);
1208
- var result = matcherFunction.apply(this, arguments);
1209
1300
 
1210
- if (this.isNot) {
1211
- result = !result;
1212
- }
1213
-
1214
- if (this.reportWasCalled_) return result;
1215
-
1216
- var message;
1217
- if (!result) {
1218
- if (this.message) {
1219
- message = this.message.apply(this, arguments);
1220
- if (jasmine.isArray_(message)) {
1221
- message = message[this.isNot ? 1 : 0];
1301
+ PrettyPrinter.prototype.format = function(value) {
1302
+ this.ppNestLevel_++;
1303
+ try {
1304
+ if (j$.util.isUndefined(value)) {
1305
+ this.emitScalar('undefined');
1306
+ } else if (value === null) {
1307
+ this.emitScalar('null');
1308
+ } else if (value === j$.getGlobal()) {
1309
+ this.emitScalar('<global>');
1310
+ } else if (value.jasmineToString) {
1311
+ this.emitScalar(value.jasmineToString());
1312
+ } else if (typeof value === 'string') {
1313
+ this.emitString(value);
1314
+ } else if (j$.isSpy(value)) {
1315
+ this.emitScalar("spy on " + value.and.identity());
1316
+ } else if (value instanceof RegExp) {
1317
+ this.emitScalar(value.toString());
1318
+ } else if (typeof value === 'function') {
1319
+ this.emitScalar('Function');
1320
+ } else if (typeof value.nodeType === 'number') {
1321
+ this.emitScalar('HTMLNode');
1322
+ } else if (value instanceof Date) {
1323
+ this.emitScalar('Date(' + value + ')');
1324
+ } else if (value.__Jasmine_been_here_before__) {
1325
+ this.emitScalar('<circular reference: ' + (j$.isArray_(value) ? 'Array' : 'Object') + '>');
1326
+ } else if (j$.isArray_(value) || typeof value == 'object') {
1327
+ value.__Jasmine_been_here_before__ = true;
1328
+ if (j$.isArray_(value)) {
1329
+ this.emitArray(value);
1330
+ } else {
1331
+ this.emitObject(value);
1222
1332
  }
1333
+ delete value.__Jasmine_been_here_before__;
1223
1334
  } else {
1224
- var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1225
- message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate;
1226
- if (matcherArgs.length > 0) {
1227
- for (var i = 0; i < matcherArgs.length; i++) {
1228
- if (i > 0) message += ",";
1229
- message += " " + jasmine.pp(matcherArgs[i]);
1230
- }
1231
- }
1232
- message += ".";
1335
+ this.emitScalar(value.toString());
1233
1336
  }
1337
+ } finally {
1338
+ this.ppNestLevel_--;
1234
1339
  }
1235
- var expectationResult = new jasmine.ExpectationResult({
1236
- matcherName: matcherName,
1237
- passed: result,
1238
- expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0],
1239
- actual: this.actual,
1240
- message: message
1241
- });
1242
- this.spec.addMatcherResult(expectationResult);
1243
- return jasmine.undefined;
1244
1340
  };
1245
- };
1246
-
1247
1341
 
1342
+ PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1343
+ for (var property in obj) {
1344
+ if (!obj.hasOwnProperty(property)) continue;
1345
+ if (property == '__Jasmine_been_here_before__') continue;
1346
+ fn(property, obj.__lookupGetter__ ? (!j$.util.isUndefined(obj.__lookupGetter__(property)) &&
1347
+ obj.__lookupGetter__(property) !== null) : false);
1348
+ }
1349
+ };
1248
1350
 
1351
+ PrettyPrinter.prototype.emitArray = j$.unimplementedMethod_;
1352
+ PrettyPrinter.prototype.emitObject = j$.unimplementedMethod_;
1353
+ PrettyPrinter.prototype.emitScalar = j$.unimplementedMethod_;
1354
+ PrettyPrinter.prototype.emitString = j$.unimplementedMethod_;
1249
1355
 
1250
- /**
1251
- * toBe: compares the actual to the expected using ===
1252
- * @param expected
1253
- */
1254
- jasmine.Matchers.prototype.toBe = function(expected) {
1255
- return this.actual === expected;
1256
- };
1356
+ function StringPrettyPrinter() {
1357
+ PrettyPrinter.call(this);
1257
1358
 
1258
- /**
1259
- * toNotBe: compares the actual to the expected using !==
1260
- * @param expected
1261
- * @deprecated as of 1.0. Use not.toBe() instead.
1262
- */
1263
- jasmine.Matchers.prototype.toNotBe = function(expected) {
1264
- return this.actual !== expected;
1265
- };
1359
+ this.string = '';
1360
+ }
1266
1361
 
1267
- /**
1268
- * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc.
1269
- *
1270
- * @param expected
1271
- */
1272
- jasmine.Matchers.prototype.toEqual = function(expected) {
1273
- return this.env.equals_(this.actual, expected);
1274
- };
1362
+ j$.util.inherit(StringPrettyPrinter, PrettyPrinter);
1275
1363
 
1276
- /**
1277
- * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1278
- * @param expected
1279
- * @deprecated as of 1.0. Use not.toEqual() instead.
1280
- */
1281
- jasmine.Matchers.prototype.toNotEqual = function(expected) {
1282
- return !this.env.equals_(this.actual, expected);
1283
- };
1364
+ StringPrettyPrinter.prototype.emitScalar = function(value) {
1365
+ this.append(value);
1366
+ };
1284
1367
 
1285
- /**
1286
- * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes
1287
- * a pattern or a String.
1288
- *
1289
- * @param expected
1290
- */
1291
- jasmine.Matchers.prototype.toMatch = function(expected) {
1292
- return new RegExp(expected).test(this.actual);
1293
- };
1368
+ StringPrettyPrinter.prototype.emitString = function(value) {
1369
+ this.append("'" + value + "'");
1370
+ };
1294
1371
 
1295
- /**
1296
- * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch
1297
- * @param expected
1298
- * @deprecated as of 1.0. Use not.toMatch() instead.
1299
- */
1300
- jasmine.Matchers.prototype.toNotMatch = function(expected) {
1301
- return !(new RegExp(expected).test(this.actual));
1302
- };
1372
+ StringPrettyPrinter.prototype.emitArray = function(array) {
1373
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
1374
+ this.append("Array");
1375
+ return;
1376
+ }
1303
1377
 
1304
- /**
1305
- * Matcher that compares the actual to jasmine.undefined.
1306
- */
1307
- jasmine.Matchers.prototype.toBeDefined = function() {
1308
- return (this.actual !== jasmine.undefined);
1309
- };
1378
+ this.append('[ ');
1379
+ for (var i = 0; i < array.length; i++) {
1380
+ if (i > 0) {
1381
+ this.append(', ');
1382
+ }
1383
+ this.format(array[i]);
1384
+ }
1385
+ this.append(' ]');
1386
+ };
1310
1387
 
1311
- /**
1312
- * Matcher that compares the actual to jasmine.undefined.
1313
- */
1314
- jasmine.Matchers.prototype.toBeUndefined = function() {
1315
- return (this.actual === jasmine.undefined);
1316
- };
1388
+ StringPrettyPrinter.prototype.emitObject = function(obj) {
1389
+ if (this.ppNestLevel_ > j$.MAX_PRETTY_PRINT_DEPTH) {
1390
+ this.append("Object");
1391
+ return;
1392
+ }
1317
1393
 
1318
- /**
1319
- * Matcher that compares the actual to null.
1320
- */
1321
- jasmine.Matchers.prototype.toBeNull = function() {
1322
- return (this.actual === null);
1323
- };
1394
+ var self = this;
1395
+ this.append('{ ');
1396
+ var first = true;
1324
1397
 
1325
- /**
1326
- * Matcher that compares the actual to NaN.
1327
- */
1328
- jasmine.Matchers.prototype.toBeNaN = function() {
1329
- this.message = function() {
1330
- return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
1331
- };
1398
+ this.iterateObject(obj, function(property, isGetter) {
1399
+ if (first) {
1400
+ first = false;
1401
+ } else {
1402
+ self.append(', ');
1403
+ }
1332
1404
 
1333
- return (this.actual !== this.actual);
1334
- };
1405
+ self.append(property);
1406
+ self.append(' : ');
1407
+ if (isGetter) {
1408
+ self.append('<getter>');
1409
+ } else {
1410
+ self.format(obj[property]);
1411
+ }
1412
+ });
1335
1413
 
1336
- /**
1337
- * Matcher that boolean not-nots the actual.
1338
- */
1339
- jasmine.Matchers.prototype.toBeTruthy = function() {
1340
- return !!this.actual;
1341
- };
1414
+ this.append(' }');
1415
+ };
1342
1416
 
1417
+ StringPrettyPrinter.prototype.append = function(value) {
1418
+ this.string += value;
1419
+ };
1343
1420
 
1344
- /**
1345
- * Matcher that boolean nots the actual.
1346
- */
1347
- jasmine.Matchers.prototype.toBeFalsy = function() {
1348
- return !this.actual;
1421
+ return function(value) {
1422
+ var stringPrettyPrinter = new StringPrettyPrinter();
1423
+ stringPrettyPrinter.format(value);
1424
+ return stringPrettyPrinter.string;
1425
+ };
1349
1426
  };
1350
1427
 
1428
+ getJasmineRequireObj().QueueRunner = function() {
1351
1429
 
1352
- /**
1353
- * Matcher that checks to see if the actual, a Jasmine spy, was called.
1354
- */
1355
- jasmine.Matchers.prototype.toHaveBeenCalled = function() {
1356
- if (arguments.length > 0) {
1357
- throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
1430
+ function QueueRunner(attrs) {
1431
+ this.fns = attrs.fns || [];
1432
+ this.onComplete = attrs.onComplete || function() {};
1433
+ this.clearStack = attrs.clearStack || function(fn) {fn();};
1434
+ this.onException = attrs.onException || function() {};
1435
+ this.catchException = attrs.catchException || function() { return true; };
1358
1436
  }
1359
1437
 
1360
- if (!jasmine.isSpy(this.actual)) {
1361
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1362
- }
1363
-
1364
- this.message = function() {
1365
- return [
1366
- "Expected spy " + this.actual.identity + " to have been called.",
1367
- "Expected spy " + this.actual.identity + " not to have been called."
1368
- ];
1438
+ QueueRunner.prototype.execute = function() {
1439
+ this.run(this.fns, 0);
1369
1440
  };
1370
1441
 
1371
- return this.actual.wasCalled;
1372
- };
1373
-
1374
- /** @deprecated Use expect(xxx).toHaveBeenCalled() instead */
1375
- jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled;
1376
-
1377
- /**
1378
- * Matcher that checks to see if the actual, a Jasmine spy, was not called.
1379
- *
1380
- * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead
1381
- */
1382
- jasmine.Matchers.prototype.wasNotCalled = function() {
1383
- if (arguments.length > 0) {
1384
- throw new Error('wasNotCalled does not take arguments');
1385
- }
1386
-
1387
- if (!jasmine.isSpy(this.actual)) {
1388
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1389
- }
1442
+ QueueRunner.prototype.run = function(fns, recursiveIndex) {
1443
+ var length = fns.length,
1444
+ self = this,
1445
+ iterativeIndex;
1390
1446
 
1391
- this.message = function() {
1392
- return [
1393
- "Expected spy " + this.actual.identity + " to not have been called.",
1394
- "Expected spy " + this.actual.identity + " to have been called."
1395
- ];
1396
- };
1447
+ for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
1448
+ var fn = fns[iterativeIndex];
1449
+ if (fn.length > 0) {
1450
+ return attemptAsync(fn);
1451
+ } else {
1452
+ attemptSync(fn);
1453
+ }
1454
+ }
1397
1455
 
1398
- return !this.actual.wasCalled;
1399
- };
1456
+ var runnerDone = iterativeIndex >= length;
1400
1457
 
1401
- /**
1402
- * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters.
1403
- *
1404
- * @example
1405
- *
1406
- */
1407
- jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
1408
- var expectedArgs = jasmine.util.argsToArray(arguments);
1409
- if (!jasmine.isSpy(this.actual)) {
1410
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1411
- }
1412
- this.message = function() {
1413
- var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
1414
- var positiveMessage = "";
1415
- if (this.actual.callCount === 0) {
1416
- positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
1417
- } else {
1418
- positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
1458
+ if (runnerDone) {
1459
+ this.clearStack(this.onComplete);
1419
1460
  }
1420
- return [positiveMessage, invertedMessage];
1421
- };
1422
1461
 
1423
- return this.env.contains_(this.actual.argsForCall, expectedArgs);
1424
- };
1462
+ function attemptSync(fn) {
1463
+ try {
1464
+ fn.call(self);
1465
+ } catch (e) {
1466
+ handleException(e);
1467
+ }
1468
+ }
1425
1469
 
1426
- /** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */
1427
- jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith;
1470
+ function attemptAsync(fn) {
1471
+ var next = function () { self.run(fns, iterativeIndex + 1); };
1428
1472
 
1429
- /** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */
1430
- jasmine.Matchers.prototype.wasNotCalledWith = function() {
1431
- var expectedArgs = jasmine.util.argsToArray(arguments);
1432
- if (!jasmine.isSpy(this.actual)) {
1433
- throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
1434
- }
1473
+ try {
1474
+ fn.call(self, next);
1475
+ } catch (e) {
1476
+ handleException(e);
1477
+ next();
1478
+ }
1479
+ }
1435
1480
 
1436
- this.message = function() {
1437
- return [
1438
- "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was",
1439
- "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was"
1440
- ];
1481
+ function handleException(e) {
1482
+ self.onException(e);
1483
+ if (!self.catchException(e)) {
1484
+ //TODO: set a var when we catch an exception and
1485
+ //use a finally block to close the loop in a nice way..
1486
+ throw e;
1487
+ }
1488
+ }
1441
1489
  };
1442
1490
 
1443
- return !this.env.contains_(this.actual.argsForCall, expectedArgs);
1491
+ return QueueRunner;
1444
1492
  };
1445
1493
 
1446
- /**
1447
- * Matcher that checks that the expected item is an element in the actual Array.
1448
- *
1449
- * @param {Object} expected
1450
- */
1451
- jasmine.Matchers.prototype.toContain = function(expected) {
1452
- return this.env.contains_(this.actual, expected);
1453
- };
1494
+ getJasmineRequireObj().ReportDispatcher = function() {
1495
+ function ReportDispatcher(methods) {
1454
1496
 
1455
- /**
1456
- * Matcher that checks that the expected item is NOT an element in the actual Array.
1457
- *
1458
- * @param {Object} expected
1459
- * @deprecated as of 1.0. Use not.toContain() instead.
1460
- */
1461
- jasmine.Matchers.prototype.toNotContain = function(expected) {
1462
- return !this.env.contains_(this.actual, expected);
1463
- };
1497
+ var dispatchedMethods = methods || [];
1464
1498
 
1465
- jasmine.Matchers.prototype.toBeLessThan = function(expected) {
1466
- return this.actual < expected;
1467
- };
1499
+ for (var i = 0; i < dispatchedMethods.length; i++) {
1500
+ var method = dispatchedMethods[i];
1501
+ this[method] = function(m) {
1502
+ return function() {
1503
+ dispatch(m, arguments);
1504
+ };
1505
+ }(method);
1506
+ }
1468
1507
 
1469
- jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
1470
- return this.actual > expected;
1471
- };
1508
+ var reporters = [];
1509
+
1510
+ this.addReporter = function(reporter) {
1511
+ reporters.push(reporter);
1512
+ };
1472
1513
 
1473
- /**
1474
- * Matcher that checks that the expected item is equal to the actual item
1475
- * up to a given level of decimal precision (default 2).
1476
- *
1477
- * @param {Number} expected
1478
- * @param {Number} precision, as number of decimal places
1479
- */
1480
- jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
1481
- if (!(precision === 0)) {
1482
- precision = precision || 2;
1514
+ return this;
1515
+
1516
+ function dispatch(method, args) {
1517
+ for (var i = 0; i < reporters.length; i++) {
1518
+ var reporter = reporters[i];
1519
+ if (reporter[method]) {
1520
+ reporter[method].apply(reporter, args);
1521
+ }
1522
+ }
1523
+ }
1483
1524
  }
1484
- return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
1525
+
1526
+ return ReportDispatcher;
1485
1527
  };
1486
1528
 
1487
- /**
1488
- * Matcher that checks that the expected exception was thrown by the actual.
1489
- *
1490
- * @param {String} [expected]
1491
- */
1492
- jasmine.Matchers.prototype.toThrow = function(expected) {
1493
- var result = false;
1494
- var exception;
1495
- if (typeof this.actual != 'function') {
1496
- throw new Error('Actual is not a function');
1497
- }
1498
- try {
1499
- this.actual();
1500
- } catch (e) {
1501
- exception = e;
1502
- }
1503
- if (exception) {
1504
- result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected));
1505
- }
1506
1529
 
1507
- var not = this.isNot ? "not " : "";
1530
+ getJasmineRequireObj().SpyStrategy = function() {
1508
1531
 
1509
- this.message = function() {
1510
- if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) {
1511
- return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' ');
1512
- } else {
1513
- return "Expected function to throw an exception.";
1514
- }
1515
- };
1532
+ function SpyStrategy(options) {
1533
+ options = options || {};
1516
1534
 
1517
- return result;
1518
- };
1535
+ var identity = options.name || "unknown",
1536
+ originalFn = options.fn || function() {},
1537
+ getSpy = options.getSpy || function() {},
1538
+ plan = function() {};
1519
1539
 
1520
- jasmine.Matchers.Any = function(expectedClass) {
1521
- this.expectedClass = expectedClass;
1522
- };
1540
+ this.identity = function() {
1541
+ return identity;
1542
+ };
1523
1543
 
1524
- jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
1525
- if (this.expectedClass == String) {
1526
- return typeof other == 'string' || other instanceof String;
1527
- }
1544
+ this.exec = function() {
1545
+ return plan.apply(this, arguments);
1546
+ };
1528
1547
 
1529
- if (this.expectedClass == Number) {
1530
- return typeof other == 'number' || other instanceof Number;
1531
- }
1548
+ this.callThrough = function() {
1549
+ plan = originalFn;
1550
+ return getSpy();
1551
+ };
1532
1552
 
1533
- if (this.expectedClass == Function) {
1534
- return typeof other == 'function' || other instanceof Function;
1535
- }
1553
+ this.callReturn = function(value) {
1554
+ plan = function() {
1555
+ return value;
1556
+ };
1557
+ return getSpy();
1558
+ };
1536
1559
 
1537
- if (this.expectedClass == Object) {
1538
- return typeof other == 'object';
1539
- }
1560
+ this.callThrow = function(something) {
1561
+ plan = function() {
1562
+ throw something;
1563
+ };
1564
+ return getSpy();
1565
+ };
1540
1566
 
1541
- return other instanceof this.expectedClass;
1542
- };
1567
+ this.callFake = function(fn) {
1568
+ plan = fn;
1569
+ return getSpy();
1570
+ };
1543
1571
 
1544
- jasmine.Matchers.Any.prototype.jasmineToString = function() {
1545
- return '<jasmine.any(' + this.expectedClass + ')>';
1546
- };
1572
+ this.stub = function(fn) {
1573
+ plan = function() {};
1574
+ return getSpy();
1575
+ };
1576
+ }
1547
1577
 
1548
- jasmine.Matchers.ObjectContaining = function (sample) {
1549
- this.sample = sample;
1578
+ return SpyStrategy;
1550
1579
  };
1551
1580
 
1552
- jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1553
- mismatchKeys = mismatchKeys || [];
1554
- mismatchValues = mismatchValues || [];
1581
+ getJasmineRequireObj().Suite = function() {
1582
+ function Suite(attrs) {
1583
+ this.env = attrs.env;
1584
+ this.id = attrs.id;
1585
+ this.parentSuite = attrs.parentSuite;
1586
+ this.description = attrs.description;
1587
+ this.onStart = attrs.onStart || function() {};
1588
+ this.completeCallback = attrs.completeCallback || function() {}; // TODO: this is unused
1589
+ this.resultCallback = attrs.resultCallback || function() {};
1590
+ this.clearStack = attrs.clearStack || function(fn) {fn();};
1555
1591
 
1556
- var env = jasmine.getEnv();
1592
+ this.beforeFns = [];
1593
+ this.afterFns = [];
1594
+ this.queueRunner = attrs.queueRunner || function() {};
1595
+ this.disabled = false;
1557
1596
 
1558
- var hasKey = function(obj, keyName) {
1559
- return obj != null && obj[keyName] !== jasmine.undefined;
1560
- };
1597
+ this.children_ = []; // TODO: rename
1598
+ this.suites = []; // TODO: needed?
1599
+ this.specs = []; // TODO: needed?
1561
1600
 
1562
- for (var property in this.sample) {
1563
- if (!hasKey(other, property) && hasKey(this.sample, property)) {
1564
- mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1565
- }
1566
- else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
1567
- mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
1568
- }
1601
+ this.result = {
1602
+ id: this.id,
1603
+ status: this.disabled ? 'disabled' : '',
1604
+ description: this.description,
1605
+ fullName: this.getFullName()
1606
+ };
1569
1607
  }
1570
1608
 
1571
- return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1572
- };
1573
-
1574
- jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
1575
- return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
1576
- };
1577
- // Mock setTimeout, clearTimeout
1578
- // Contributed by Pivotal Computer Systems, www.pivotalsf.com
1609
+ Suite.prototype.getFullName = function() {
1610
+ var fullName = this.description;
1611
+ for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
1612
+ if (parentSuite.parentSuite) {
1613
+ fullName = parentSuite.description + ' ' + fullName;
1614
+ }
1615
+ }
1616
+ return fullName;
1617
+ };
1579
1618
 
1580
- jasmine.FakeTimer = function() {
1581
- this.reset();
1619
+ Suite.prototype.disable = function() {
1620
+ this.disabled = true;
1621
+ };
1582
1622
 
1583
- var self = this;
1584
- self.setTimeout = function(funcToCall, millis) {
1585
- self.timeoutsMade++;
1586
- self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
1587
- return self.timeoutsMade;
1623
+ Suite.prototype.beforeEach = function(fn) {
1624
+ this.beforeFns.unshift(fn);
1588
1625
  };
1589
1626
 
1590
- self.setInterval = function(funcToCall, millis) {
1591
- self.timeoutsMade++;
1592
- self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
1593
- return self.timeoutsMade;
1627
+ Suite.prototype.afterEach = function(fn) {
1628
+ this.afterFns.unshift(fn);
1594
1629
  };
1595
1630
 
1596
- self.clearTimeout = function(timeoutKey) {
1597
- self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1631
+ Suite.prototype.addSpec = function(spec) {
1632
+ this.children_.push(spec);
1633
+ this.specs.push(spec); // TODO: needed?
1598
1634
  };
1599
1635
 
1600
- self.clearInterval = function(timeoutKey) {
1601
- self.scheduledFunctions[timeoutKey] = jasmine.undefined;
1636
+ Suite.prototype.addSuite = function(suite) {
1637
+ suite.parentSuite = this;
1638
+ this.children_.push(suite);
1639
+ this.suites.push(suite); // TODO: needed?
1602
1640
  };
1603
1641
 
1604
- };
1642
+ Suite.prototype.children = function() {
1643
+ return this.children_;
1644
+ };
1605
1645
 
1606
- jasmine.FakeTimer.prototype.reset = function() {
1607
- this.timeoutsMade = 0;
1608
- this.scheduledFunctions = {};
1609
- this.nowMillis = 0;
1610
- };
1646
+ Suite.prototype.execute = function(onComplete) {
1647
+ var self = this;
1648
+ if (this.disabled) {
1649
+ complete();
1650
+ return;
1651
+ }
1611
1652
 
1612
- jasmine.FakeTimer.prototype.tick = function(millis) {
1613
- var oldMillis = this.nowMillis;
1614
- var newMillis = oldMillis + millis;
1615
- this.runFunctionsWithinRange(oldMillis, newMillis);
1616
- this.nowMillis = newMillis;
1617
- };
1653
+ var allFns = [],
1654
+ children = this.children_;
1618
1655
 
1619
- jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
1620
- var scheduledFunc;
1621
- var funcsToRun = [];
1622
- for (var timeoutKey in this.scheduledFunctions) {
1623
- scheduledFunc = this.scheduledFunctions[timeoutKey];
1624
- if (scheduledFunc != jasmine.undefined &&
1625
- scheduledFunc.runAtMillis >= oldMillis &&
1626
- scheduledFunc.runAtMillis <= nowMillis) {
1627
- funcsToRun.push(scheduledFunc);
1628
- this.scheduledFunctions[timeoutKey] = jasmine.undefined;
1656
+ for (var i = 0; i < children.length; i++) {
1657
+ allFns.push(wrapChildAsAsync(children[i]));
1629
1658
  }
1630
- }
1631
1659
 
1632
- if (funcsToRun.length > 0) {
1633
- funcsToRun.sort(function(a, b) {
1634
- return a.runAtMillis - b.runAtMillis;
1660
+ this.onStart(this);
1661
+
1662
+ this.queueRunner({
1663
+ fns: allFns,
1664
+ onComplete: complete
1635
1665
  });
1636
- for (var i = 0; i < funcsToRun.length; ++i) {
1637
- try {
1638
- var funcToRun = funcsToRun[i];
1639
- this.nowMillis = funcToRun.runAtMillis;
1640
- funcToRun.funcToCall();
1641
- if (funcToRun.recurring) {
1642
- this.scheduleFunction(funcToRun.timeoutKey,
1643
- funcToRun.funcToCall,
1644
- funcToRun.millis,
1645
- true);
1646
- }
1647
- } catch(e) {
1666
+
1667
+ function complete() {
1668
+ self.resultCallback(self.result);
1669
+
1670
+ if (onComplete) {
1671
+ onComplete();
1648
1672
  }
1649
1673
  }
1650
- this.runFunctionsWithinRange(oldMillis, nowMillis);
1674
+
1675
+ function wrapChildAsAsync(child) {
1676
+ return function(done) { child.execute(done); };
1677
+ }
1678
+ };
1679
+
1680
+ return Suite;
1681
+ };
1682
+
1683
+ if (typeof window == void 0 && typeof exports == "object") {
1684
+ exports.Suite = jasmineRequire.Suite;
1685
+ }
1686
+
1687
+ getJasmineRequireObj().Timer = function() {
1688
+ function Timer(options) {
1689
+ options = options || {};
1690
+
1691
+ var now = options.now || function() { return new Date().getTime(); },
1692
+ startTime;
1693
+
1694
+ this.start = function() {
1695
+ startTime = now();
1696
+ };
1697
+
1698
+ this.elapsed = function() {
1699
+ return now() - startTime;
1700
+ };
1651
1701
  }
1652
- };
1653
1702
 
1654
- jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
1655
- this.scheduledFunctions[timeoutKey] = {
1656
- runAtMillis: this.nowMillis + millis,
1657
- funcToCall: funcToCall,
1658
- recurring: recurring,
1659
- timeoutKey: timeoutKey,
1660
- millis: millis
1661
- };
1703
+ return Timer;
1662
1704
  };
1705
+ getJasmineRequireObj().matchersUtil = function(j$) {
1706
+ // TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
1663
1707
 
1664
- /**
1665
- * @namespace
1666
- */
1667
- jasmine.Clock = {
1668
- defaultFakeTimer: new jasmine.FakeTimer(),
1708
+ return {
1709
+ equals: function(a, b, customTesters) {
1710
+ customTesters = customTesters || [];
1669
1711
 
1670
- reset: function() {
1671
- jasmine.Clock.assertInstalled();
1672
- jasmine.Clock.defaultFakeTimer.reset();
1673
- },
1712
+ return eq(a, b, [], [], customTesters);
1713
+ },
1674
1714
 
1675
- tick: function(millis) {
1676
- jasmine.Clock.assertInstalled();
1677
- jasmine.Clock.defaultFakeTimer.tick(millis);
1678
- },
1715
+ contains: function(haystack, needle, customTesters) {
1716
+ customTesters = customTesters || [];
1679
1717
 
1680
- runFunctionsWithinRange: function(oldMillis, nowMillis) {
1681
- jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
1682
- },
1718
+ if (Object.prototype.toString.apply(haystack) === "[object Array]") {
1719
+ for (var i = 0; i < haystack.length; i++) {
1720
+ if (eq(haystack[i], needle, [], [], customTesters)) {
1721
+ return true;
1722
+ }
1723
+ }
1724
+ return false;
1725
+ }
1726
+ return haystack.indexOf(needle) >= 0;
1727
+ },
1728
+
1729
+ buildFailureMessage: function() {
1730
+ var args = Array.prototype.slice.call(arguments, 0),
1731
+ matcherName = args[0],
1732
+ isNot = args[1],
1733
+ actual = args[2],
1734
+ expected = args.slice(3),
1735
+ englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); });
1736
+
1737
+ var message = "Expected " +
1738
+ j$.pp(actual) +
1739
+ (isNot ? " not " : " ") +
1740
+ englishyPredicate;
1741
+
1742
+ if (expected.length > 0) {
1743
+ for (var i = 0; i < expected.length; i++) {
1744
+ if (i > 0) message += ",";
1745
+ message += " " + j$.pp(expected[i]);
1746
+ }
1747
+ }
1683
1748
 
1684
- scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
1685
- jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
1686
- },
1749
+ return message + ".";
1750
+ }
1751
+ };
1687
1752
 
1688
- useMock: function() {
1689
- if (!jasmine.Clock.isInstalled()) {
1690
- var spec = jasmine.getEnv().currentSpec;
1691
- spec.after(jasmine.Clock.uninstallMock);
1753
+ // Equality function lovingly adapted from isEqual in
1754
+ // [Underscore](http://underscorejs.org)
1755
+ function eq(a, b, aStack, bStack, customTesters) {
1756
+ var result = true;
1692
1757
 
1693
- jasmine.Clock.installMock();
1758
+ for (var i = 0; i < customTesters.length; i++) {
1759
+ result = customTesters[i](a, b);
1760
+ if (result) {
1761
+ return true;
1762
+ }
1694
1763
  }
1695
- },
1696
-
1697
- installMock: function() {
1698
- jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
1699
- },
1700
1764
 
1701
- uninstallMock: function() {
1702
- jasmine.Clock.assertInstalled();
1703
- jasmine.Clock.installed = jasmine.Clock.real;
1704
- },
1765
+ if (a instanceof j$.Any) {
1766
+ result = a.jasmineMatches(b);
1767
+ if (result) {
1768
+ return true;
1769
+ }
1770
+ }
1705
1771
 
1706
- real: {
1707
- setTimeout: jasmine.getGlobal().setTimeout,
1708
- clearTimeout: jasmine.getGlobal().clearTimeout,
1709
- setInterval: jasmine.getGlobal().setInterval,
1710
- clearInterval: jasmine.getGlobal().clearInterval
1711
- },
1772
+ if (b instanceof j$.Any) {
1773
+ result = b.jasmineMatches(a);
1774
+ if (result) {
1775
+ return true;
1776
+ }
1777
+ }
1712
1778
 
1713
- assertInstalled: function() {
1714
- if (!jasmine.Clock.isInstalled()) {
1715
- throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
1779
+ if (b instanceof j$.ObjectContaining) {
1780
+ result = b.jasmineMatches(a);
1781
+ if (result) {
1782
+ return true;
1783
+ }
1716
1784
  }
1717
- },
1718
1785
 
1719
- isInstalled: function() {
1720
- return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
1721
- },
1786
+ if (a instanceof Error && b instanceof Error) {
1787
+ return a.message == b.message;
1788
+ }
1722
1789
 
1723
- installed: null
1724
- };
1725
- jasmine.Clock.installed = jasmine.Clock.real;
1790
+ // Identical objects are equal. `0 === -0`, but they aren't identical.
1791
+ // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
1792
+ if (a === b) return a !== 0 || 1 / a == 1 / b;
1793
+ // A strict comparison is necessary because `null == undefined`.
1794
+ if (a === null || b === null) return a === b;
1795
+ var className = Object.prototype.toString.call(a);
1796
+ if (className != Object.prototype.toString.call(b)) return false;
1797
+ switch (className) {
1798
+ // Strings, numbers, dates, and booleans are compared by value.
1799
+ case '[object String]':
1800
+ // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
1801
+ // equivalent to `new String("5")`.
1802
+ return a == String(b);
1803
+ case '[object Number]':
1804
+ // `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
1805
+ // other numeric values.
1806
+ return a != +a ? b != +b : (a === 0 ? 1 / a == 1 / b : a == +b);
1807
+ case '[object Date]':
1808
+ case '[object Boolean]':
1809
+ // Coerce dates and booleans to numeric primitive values. Dates are compared by their
1810
+ // millisecond representations. Note that invalid dates with millisecond representations
1811
+ // of `NaN` are not equivalent.
1812
+ return +a == +b;
1813
+ // RegExps are compared by their source patterns and flags.
1814
+ case '[object RegExp]':
1815
+ return a.source == b.source &&
1816
+ a.global == b.global &&
1817
+ a.multiline == b.multiline &&
1818
+ a.ignoreCase == b.ignoreCase;
1819
+ }
1820
+ if (typeof a != 'object' || typeof b != 'object') return false;
1821
+ // Assume equality for cyclic structures. The algorithm for detecting cyclic
1822
+ // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
1823
+ var length = aStack.length;
1824
+ while (length--) {
1825
+ // Linear search. Performance is inversely proportional to the number of
1826
+ // unique nested structures.
1827
+ if (aStack[length] == a) return bStack[length] == b;
1828
+ }
1829
+ // Add the first object to the stack of traversed objects.
1830
+ aStack.push(a);
1831
+ bStack.push(b);
1832
+ var size = 0;
1833
+ // Recursively compare objects and arrays.
1834
+ if (className == '[object Array]') {
1835
+ // Compare array lengths to determine if a deep comparison is necessary.
1836
+ size = a.length;
1837
+ result = size == b.length;
1838
+ if (result) {
1839
+ // Deep compare the contents, ignoring non-numeric properties.
1840
+ while (size--) {
1841
+ if (!(result = eq(a[size], b[size], aStack, bStack, customTesters))) break;
1842
+ }
1843
+ }
1844
+ } else {
1845
+ // Objects with different constructors are not equivalent, but `Object`s
1846
+ // from different frames are.
1847
+ var aCtor = a.constructor, bCtor = b.constructor;
1848
+ if (aCtor !== bCtor && !(isFunction(aCtor) && (aCtor instanceof aCtor) &&
1849
+ isFunction(bCtor) && (bCtor instanceof bCtor))) {
1850
+ return false;
1851
+ }
1852
+ // Deep compare objects.
1853
+ for (var key in a) {
1854
+ if (has(a, key)) {
1855
+ // Count the expected number of properties.
1856
+ size++;
1857
+ // Deep compare each member.
1858
+ if (!(result = has(b, key) && eq(a[key], b[key], aStack, bStack, customTesters))) break;
1859
+ }
1860
+ }
1861
+ // Ensure that both objects contain the same number of properties.
1862
+ if (result) {
1863
+ for (key in b) {
1864
+ if (has(b, key) && !(size--)) break;
1865
+ }
1866
+ result = !size;
1867
+ }
1868
+ }
1869
+ // Remove the first object from the stack of traversed objects.
1870
+ aStack.pop();
1871
+ bStack.pop();
1726
1872
 
1727
- //else for IE support
1728
- jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
1729
- if (jasmine.Clock.installed.setTimeout.apply) {
1730
- return jasmine.Clock.installed.setTimeout.apply(this, arguments);
1731
- } else {
1732
- return jasmine.Clock.installed.setTimeout(funcToCall, millis);
1733
- }
1734
- };
1873
+ return result;
1735
1874
 
1736
- jasmine.getGlobal().setInterval = function(funcToCall, millis) {
1737
- if (jasmine.Clock.installed.setInterval.apply) {
1738
- return jasmine.Clock.installed.setInterval.apply(this, arguments);
1739
- } else {
1740
- return jasmine.Clock.installed.setInterval(funcToCall, millis);
1741
- }
1742
- };
1875
+ function has(obj, key) {
1876
+ return obj.hasOwnProperty(key);
1877
+ }
1743
1878
 
1744
- jasmine.getGlobal().clearTimeout = function(timeoutKey) {
1745
- if (jasmine.Clock.installed.clearTimeout.apply) {
1746
- return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
1747
- } else {
1748
- return jasmine.Clock.installed.clearTimeout(timeoutKey);
1879
+ function isFunction(obj) {
1880
+ return typeof obj === 'function';
1881
+ }
1749
1882
  }
1750
1883
  };
1751
-
1752
- jasmine.getGlobal().clearInterval = function(timeoutKey) {
1753
- if (jasmine.Clock.installed.clearTimeout.apply) {
1754
- return jasmine.Clock.installed.clearInterval.apply(this, arguments);
1755
- } else {
1756
- return jasmine.Clock.installed.clearInterval(timeoutKey);
1884
+ getJasmineRequireObj().toBe = function() {
1885
+ function toBe() {
1886
+ return {
1887
+ compare: function(actual, expected) {
1888
+ return {
1889
+ pass: actual === expected
1890
+ };
1891
+ }
1892
+ };
1757
1893
  }
1758
- };
1759
1894
 
1760
- /**
1761
- * @constructor
1762
- */
1763
- jasmine.MultiReporter = function() {
1764
- this.subReporters_ = [];
1895
+ return toBe;
1765
1896
  };
1766
- jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter);
1767
1897
 
1768
- jasmine.MultiReporter.prototype.addReporter = function(reporter) {
1769
- this.subReporters_.push(reporter);
1770
- };
1898
+ getJasmineRequireObj().toBeCloseTo = function() {
1771
1899
 
1772
- (function() {
1773
- var functionNames = [
1774
- "reportRunnerStarting",
1775
- "reportRunnerResults",
1776
- "reportSuiteResults",
1777
- "reportSpecStarting",
1778
- "reportSpecResults",
1779
- "log"
1780
- ];
1781
- for (var i = 0; i < functionNames.length; i++) {
1782
- var functionName = functionNames[i];
1783
- jasmine.MultiReporter.prototype[functionName] = (function(functionName) {
1784
- return function() {
1785
- for (var j = 0; j < this.subReporters_.length; j++) {
1786
- var subReporter = this.subReporters_[j];
1787
- if (subReporter[functionName]) {
1788
- subReporter[functionName].apply(subReporter, arguments);
1789
- }
1900
+ function toBeCloseTo() {
1901
+ return {
1902
+ compare: function(actual, expected, precision) {
1903
+ if (precision !== 0) {
1904
+ precision = precision || 2;
1790
1905
  }
1791
- };
1792
- })(functionName);
1793
- }
1794
- })();
1795
- /**
1796
- * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults
1797
- *
1798
- * @constructor
1799
- */
1800
- jasmine.NestedResults = function() {
1801
- /**
1802
- * The total count of results
1803
- */
1804
- this.totalCount = 0;
1805
- /**
1806
- * Number of passed results
1807
- */
1808
- this.passedCount = 0;
1809
- /**
1810
- * Number of failed results
1811
- */
1812
- this.failedCount = 0;
1813
- /**
1814
- * Was this suite/spec skipped?
1815
- */
1816
- this.skipped = false;
1817
- /**
1818
- * @ignore
1819
- */
1820
- this.items_ = [];
1821
- };
1822
-
1823
- /**
1824
- * Roll up the result counts.
1825
- *
1826
- * @param result
1827
- */
1828
- jasmine.NestedResults.prototype.rollupCounts = function(result) {
1829
- this.totalCount += result.totalCount;
1830
- this.passedCount += result.passedCount;
1831
- this.failedCount += result.failedCount;
1832
- };
1833
1906
 
1834
- /**
1835
- * Adds a log message.
1836
- * @param values Array of message parts which will be concatenated later.
1837
- */
1838
- jasmine.NestedResults.prototype.log = function(values) {
1839
- this.items_.push(new jasmine.MessageResult(values));
1840
- };
1907
+ return {
1908
+ pass: Math.abs(expected - actual) < (Math.pow(10, -precision) / 2)
1909
+ };
1910
+ }
1911
+ };
1912
+ }
1841
1913
 
1842
- /**
1843
- * Getter for the results: message & results.
1844
- */
1845
- jasmine.NestedResults.prototype.getItems = function() {
1846
- return this.items_;
1914
+ return toBeCloseTo;
1847
1915
  };
1848
1916
 
1849
- /**
1850
- * Adds a result, tracking counts (total, passed, & failed)
1851
- * @param {jasmine.ExpectationResult|jasmine.NestedResults} result
1852
- */
1853
- jasmine.NestedResults.prototype.addResult = function(result) {
1854
- if (result.type != 'log') {
1855
- if (result.items_) {
1856
- this.rollupCounts(result);
1857
- } else {
1858
- this.totalCount++;
1859
- if (result.passed()) {
1860
- this.passedCount++;
1861
- } else {
1862
- this.failedCount++;
1917
+ getJasmineRequireObj().toBeDefined = function() {
1918
+ function toBeDefined() {
1919
+ return {
1920
+ compare: function(actual) {
1921
+ return {
1922
+ pass: (void 0 !== actual)
1923
+ };
1863
1924
  }
1864
- }
1925
+ };
1865
1926
  }
1866
- this.items_.push(result);
1867
- };
1868
1927
 
1869
- /**
1870
- * @returns {Boolean} True if <b>everything</b> below passed
1871
- */
1872
- jasmine.NestedResults.prototype.passed = function() {
1873
- return this.passedCount === this.totalCount;
1874
- };
1875
- /**
1876
- * Base class for pretty printing for expectation results.
1877
- */
1878
- jasmine.PrettyPrinter = function() {
1879
- this.ppNestLevel_ = 0;
1928
+ return toBeDefined;
1880
1929
  };
1881
1930
 
1882
- /**
1883
- * Formats a value in a nice, human-readable string.
1884
- *
1885
- * @param value
1886
- */
1887
- jasmine.PrettyPrinter.prototype.format = function(value) {
1888
- this.ppNestLevel_++;
1889
- try {
1890
- if (value === jasmine.undefined) {
1891
- this.emitScalar('undefined');
1892
- } else if (value === null) {
1893
- this.emitScalar('null');
1894
- } else if (value === jasmine.getGlobal()) {
1895
- this.emitScalar('<global>');
1896
- } else if (value.jasmineToString) {
1897
- this.emitScalar(value.jasmineToString());
1898
- } else if (typeof value === 'string') {
1899
- this.emitString(value);
1900
- } else if (jasmine.isSpy(value)) {
1901
- this.emitScalar("spy on " + value.identity);
1902
- } else if (value instanceof RegExp) {
1903
- this.emitScalar(value.toString());
1904
- } else if (typeof value === 'function') {
1905
- this.emitScalar('Function');
1906
- } else if (typeof value.nodeType === 'number') {
1907
- this.emitScalar('HTMLNode');
1908
- } else if (value instanceof Date) {
1909
- this.emitScalar('Date(' + value + ')');
1910
- } else if (value.__Jasmine_been_here_before__) {
1911
- this.emitScalar('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>');
1912
- } else if (jasmine.isArray_(value) || typeof value == 'object') {
1913
- value.__Jasmine_been_here_before__ = true;
1914
- if (jasmine.isArray_(value)) {
1915
- this.emitArray(value);
1916
- } else {
1917
- this.emitObject(value);
1931
+ getJasmineRequireObj().toBeFalsy = function() {
1932
+ function toBeFalsy() {
1933
+ return {
1934
+ compare: function(actual) {
1935
+ return {
1936
+ pass: !!!actual
1937
+ };
1918
1938
  }
1919
- delete value.__Jasmine_been_here_before__;
1920
- } else {
1921
- this.emitScalar(value.toString());
1922
- }
1923
- } finally {
1924
- this.ppNestLevel_--;
1939
+ };
1925
1940
  }
1926
- };
1927
1941
 
1928
- jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
1929
- for (var property in obj) {
1930
- if (!obj.hasOwnProperty(property)) continue;
1931
- if (property == '__Jasmine_been_here_before__') continue;
1932
- fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
1933
- obj.__lookupGetter__(property) !== null) : false);
1934
- }
1942
+ return toBeFalsy;
1935
1943
  };
1936
1944
 
1937
- jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_;
1938
- jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_;
1939
- jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_;
1940
- jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_;
1945
+ getJasmineRequireObj().toBeGreaterThan = function() {
1941
1946
 
1942
- jasmine.StringPrettyPrinter = function() {
1943
- jasmine.PrettyPrinter.call(this);
1947
+ function toBeGreaterThan() {
1948
+ return {
1949
+ compare: function(actual, expected) {
1950
+ return {
1951
+ pass: actual > expected
1952
+ };
1953
+ }
1954
+ };
1955
+ }
1944
1956
 
1945
- this.string = '';
1957
+ return toBeGreaterThan;
1946
1958
  };
1947
- jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter);
1948
1959
 
1949
- jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) {
1950
- this.append(value);
1951
- };
1952
1960
 
1953
- jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
1954
- this.append("'" + value + "'");
1955
- };
1961
+ getJasmineRequireObj().toBeLessThan = function() {
1962
+ function toBeLessThan() {
1963
+ return {
1956
1964
 
1957
- jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
1958
- if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1959
- this.append("Array");
1960
- return;
1965
+ compare: function(actual, expected) {
1966
+ return {
1967
+ pass: actual < expected
1968
+ };
1969
+ }
1970
+ };
1961
1971
  }
1962
1972
 
1963
- this.append('[ ');
1964
- for (var i = 0; i < array.length; i++) {
1965
- if (i > 0) {
1966
- this.append(', ');
1967
- }
1968
- this.format(array[i]);
1969
- }
1970
- this.append(' ]');
1973
+ return toBeLessThan;
1971
1974
  };
1975
+ getJasmineRequireObj().toBeNaN = function(j$) {
1972
1976
 
1973
- jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
1974
- if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
1975
- this.append("Object");
1976
- return;
1977
- }
1978
-
1979
- var self = this;
1980
- this.append('{ ');
1981
- var first = true;
1977
+ function toBeNaN() {
1978
+ return {
1979
+ compare: function(actual) {
1980
+ var result = {
1981
+ pass: (actual !== actual)
1982
+ };
1982
1983
 
1983
- this.iterateObject(obj, function(property, isGetter) {
1984
- if (first) {
1985
- first = false;
1986
- } else {
1987
- self.append(', ');
1988
- }
1984
+ if (result.pass) {
1985
+ result.message = "Expected actual not to be NaN.";
1986
+ } else {
1987
+ result.message = "Expected " + j$.pp(actual) + " to be NaN.";
1988
+ }
1989
1989
 
1990
- self.append(property);
1991
- self.append(' : ');
1992
- if (isGetter) {
1993
- self.append('<getter>');
1994
- } else {
1995
- self.format(obj[property]);
1996
- }
1997
- });
1990
+ return result;
1991
+ }
1992
+ };
1993
+ }
1998
1994
 
1999
- this.append(' }');
1995
+ return toBeNaN;
2000
1996
  };
2001
1997
 
2002
- jasmine.StringPrettyPrinter.prototype.append = function(value) {
2003
- this.string += value;
2004
- };
2005
- jasmine.Queue = function(env) {
2006
- this.env = env;
2007
-
2008
- // parallel to blocks. each true value in this array means the block will
2009
- // get executed even if we abort
2010
- this.ensured = [];
2011
- this.blocks = [];
2012
- this.running = false;
2013
- this.index = 0;
2014
- this.offset = 0;
2015
- this.abort = false;
2016
- };
1998
+ getJasmineRequireObj().toBeNull = function() {
2017
1999
 
2018
- jasmine.Queue.prototype.addBefore = function(block, ensure) {
2019
- if (ensure === jasmine.undefined) {
2020
- ensure = false;
2000
+ function toBeNull() {
2001
+ return {
2002
+ compare: function(actual) {
2003
+ return {
2004
+ pass: actual === null
2005
+ };
2006
+ }
2007
+ };
2021
2008
  }
2022
2009
 
2023
- this.blocks.unshift(block);
2024
- this.ensured.unshift(ensure);
2010
+ return toBeNull;
2025
2011
  };
2026
2012
 
2027
- jasmine.Queue.prototype.add = function(block, ensure) {
2028
- if (ensure === jasmine.undefined) {
2029
- ensure = false;
2030
- }
2031
-
2032
- this.blocks.push(block);
2033
- this.ensured.push(ensure);
2034
- };
2013
+ getJasmineRequireObj().toBeTruthy = function() {
2035
2014
 
2036
- jasmine.Queue.prototype.insertNext = function(block, ensure) {
2037
- if (ensure === jasmine.undefined) {
2038
- ensure = false;
2015
+ function toBeTruthy() {
2016
+ return {
2017
+ compare: function(actual) {
2018
+ return {
2019
+ pass: !!actual
2020
+ };
2021
+ }
2022
+ };
2039
2023
  }
2040
2024
 
2041
- this.ensured.splice((this.index + this.offset + 1), 0, ensure);
2042
- this.blocks.splice((this.index + this.offset + 1), 0, block);
2043
- this.offset++;
2044
- };
2045
-
2046
- jasmine.Queue.prototype.start = function(onComplete) {
2047
- this.running = true;
2048
- this.onComplete = onComplete;
2049
- this.next_();
2050
- };
2051
-
2052
- jasmine.Queue.prototype.isRunning = function() {
2053
- return this.running;
2025
+ return toBeTruthy;
2054
2026
  };
2055
2027
 
2056
- jasmine.Queue.LOOP_DONT_RECURSE = true;
2057
-
2058
- jasmine.Queue.prototype.next_ = function() {
2059
- var self = this;
2060
- var goAgain = true;
2061
-
2062
- while (goAgain) {
2063
- goAgain = false;
2064
-
2065
- if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
2066
- var calledSynchronously = true;
2067
- var completedSynchronously = false;
2068
-
2069
- var onComplete = function () {
2070
- if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) {
2071
- completedSynchronously = true;
2072
- return;
2073
- }
2074
-
2075
- if (self.blocks[self.index].abort) {
2076
- self.abort = true;
2077
- }
2078
-
2079
- self.offset = 0;
2080
- self.index++;
2081
-
2082
- var now = new Date().getTime();
2083
- if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) {
2084
- self.env.lastUpdate = now;
2085
- self.env.setTimeout(function() {
2086
- self.next_();
2087
- }, 0);
2088
- } else {
2089
- if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) {
2090
- goAgain = true;
2091
- } else {
2092
- self.next_();
2093
- }
2094
- }
2095
- };
2096
- self.blocks[self.index].execute(onComplete);
2028
+ getJasmineRequireObj().toBeUndefined = function() {
2097
2029
 
2098
- calledSynchronously = false;
2099
- if (completedSynchronously) {
2100
- onComplete();
2101
- }
2102
-
2103
- } else {
2104
- self.running = false;
2105
- if (self.onComplete) {
2106
- self.onComplete();
2030
+ function toBeUndefined() {
2031
+ return {
2032
+ compare: function(actual) {
2033
+ return {
2034
+ pass: void 0 === actual
2035
+ };
2107
2036
  }
2108
- }
2037
+ };
2109
2038
  }
2110
- };
2111
2039
 
2112
- jasmine.Queue.prototype.results = function() {
2113
- var results = new jasmine.NestedResults();
2114
- for (var i = 0; i < this.blocks.length; i++) {
2115
- if (this.blocks[i].results) {
2116
- results.addResult(this.blocks[i].results());
2117
- }
2118
- }
2119
- return results;
2040
+ return toBeUndefined;
2120
2041
  };
2121
2042
 
2043
+ getJasmineRequireObj().toContain = function() {
2044
+ function toContain(util, customEqualityTesters) {
2045
+ customEqualityTesters = customEqualityTesters || [];
2122
2046
 
2123
- /**
2124
- * Runner
2125
- *
2126
- * @constructor
2127
- * @param {jasmine.Env} env
2128
- */
2129
- jasmine.Runner = function(env) {
2130
- var self = this;
2131
- self.env = env;
2132
- self.queue = new jasmine.Queue(env);
2133
- self.before_ = [];
2134
- self.after_ = [];
2135
- self.suites_ = [];
2136
- };
2047
+ return {
2048
+ compare: function(actual, expected) {
2137
2049
 
2138
- jasmine.Runner.prototype.execute = function() {
2139
- var self = this;
2140
- if (self.env.reporter.reportRunnerStarting) {
2141
- self.env.reporter.reportRunnerStarting(this);
2050
+ return {
2051
+ pass: util.contains(actual, expected, customEqualityTesters)
2052
+ };
2053
+ }
2054
+ };
2142
2055
  }
2143
- self.queue.start(function () {
2144
- self.finishCallback();
2145
- });
2146
- };
2147
2056
 
2148
- jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) {
2149
- beforeEachFunction.typeName = 'beforeEach';
2150
- this.before_.splice(0,0,beforeEachFunction);
2151
- };
2152
-
2153
- jasmine.Runner.prototype.afterEach = function(afterEachFunction) {
2154
- afterEachFunction.typeName = 'afterEach';
2155
- this.after_.splice(0,0,afterEachFunction);
2057
+ return toContain;
2156
2058
  };
2157
2059
 
2060
+ getJasmineRequireObj().toEqual = function() {
2158
2061
 
2159
- jasmine.Runner.prototype.finishCallback = function() {
2160
- this.env.reporter.reportRunnerResults(this);
2161
- };
2062
+ function toEqual(util, customEqualityTesters) {
2063
+ customEqualityTesters = customEqualityTesters || [];
2162
2064
 
2163
- jasmine.Runner.prototype.addSuite = function(suite) {
2164
- this.suites_.push(suite);
2165
- };
2065
+ return {
2066
+ compare: function(actual, expected) {
2067
+ var result = {
2068
+ pass: false
2069
+ };
2166
2070
 
2167
- jasmine.Runner.prototype.add = function(block) {
2168
- if (block instanceof jasmine.Suite) {
2169
- this.addSuite(block);
2170
- }
2171
- this.queue.add(block);
2172
- };
2071
+ result.pass = util.equals(actual, expected, customEqualityTesters);
2173
2072
 
2174
- jasmine.Runner.prototype.specs = function () {
2175
- var suites = this.suites();
2176
- var specs = [];
2177
- for (var i = 0; i < suites.length; i++) {
2178
- specs = specs.concat(suites[i].specs());
2073
+ return result;
2074
+ }
2075
+ };
2179
2076
  }
2180
- return specs;
2181
- };
2182
-
2183
- jasmine.Runner.prototype.suites = function() {
2184
- return this.suites_;
2185
- };
2186
2077
 
2187
- jasmine.Runner.prototype.topLevelSuites = function() {
2188
- var topLevelSuites = [];
2189
- for (var i = 0; i < this.suites_.length; i++) {
2190
- if (!this.suites_[i].parentSuite) {
2191
- topLevelSuites.push(this.suites_[i]);
2192
- }
2193
- }
2194
- return topLevelSuites;
2078
+ return toEqual;
2195
2079
  };
2196
2080
 
2197
- jasmine.Runner.prototype.results = function() {
2198
- return this.queue.results();
2199
- };
2200
- /**
2201
- * Internal representation of a Jasmine specification, or test.
2202
- *
2203
- * @constructor
2204
- * @param {jasmine.Env} env
2205
- * @param {jasmine.Suite} suite
2206
- * @param {String} description
2207
- */
2208
- jasmine.Spec = function(env, suite, description) {
2209
- if (!env) {
2210
- throw new Error('jasmine.Env() required');
2211
- }
2212
- if (!suite) {
2213
- throw new Error('jasmine.Suite() required');
2214
- }
2215
- var spec = this;
2216
- spec.id = env.nextSpecId ? env.nextSpecId() : null;
2217
- spec.env = env;
2218
- spec.suite = suite;
2219
- spec.description = description;
2220
- spec.queue = new jasmine.Queue(env);
2221
-
2222
- spec.afterCallbacks = [];
2223
- spec.spies_ = [];
2224
-
2225
- spec.results_ = new jasmine.NestedResults();
2226
- spec.results_.description = description;
2227
- spec.matchersClass = null;
2228
- };
2081
+ getJasmineRequireObj().toHaveBeenCalled = function(j$) {
2229
2082
 
2230
- jasmine.Spec.prototype.getFullName = function() {
2231
- return this.suite.getFullName() + ' ' + this.description + '.';
2232
- };
2083
+ function toHaveBeenCalled() {
2084
+ return {
2085
+ compare: function(actual) {
2086
+ var result = {};
2233
2087
 
2088
+ if (!j$.isSpy(actual)) {
2089
+ throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
2090
+ }
2234
2091
 
2235
- jasmine.Spec.prototype.results = function() {
2236
- return this.results_;
2237
- };
2092
+ if (arguments.length > 1) {
2093
+ throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith');
2094
+ }
2238
2095
 
2239
- /**
2240
- * All parameters are pretty-printed and concatenated together, then written to the spec's output.
2241
- *
2242
- * Be careful not to leave calls to <code>jasmine.log</code> in production code.
2243
- */
2244
- jasmine.Spec.prototype.log = function() {
2245
- return this.results_.log(arguments);
2246
- };
2096
+ result.pass = actual.calls.any();
2247
2097
 
2248
- jasmine.Spec.prototype.runs = function (func) {
2249
- var block = new jasmine.Block(this.env, func, this);
2250
- this.addToQueue(block);
2251
- return this;
2252
- };
2098
+ result.message = result.pass ?
2099
+ "Expected spy " + actual.and.identity() + " not to have been called." :
2100
+ "Expected spy " + actual.and.identity() + " to have been called.";
2253
2101
 
2254
- jasmine.Spec.prototype.addToQueue = function (block) {
2255
- if (this.queue.isRunning()) {
2256
- this.queue.insertNext(block);
2257
- } else {
2258
- this.queue.add(block);
2102
+ return result;
2103
+ }
2104
+ };
2259
2105
  }
2260
- };
2261
2106
 
2262
- /**
2263
- * @param {jasmine.ExpectationResult} result
2264
- */
2265
- jasmine.Spec.prototype.addMatcherResult = function(result) {
2266
- this.results_.addResult(result);
2107
+ return toHaveBeenCalled;
2267
2108
  };
2268
2109
 
2269
- jasmine.Spec.prototype.expect = function(actual) {
2270
- var positive = new (this.getMatchersClass_())(this.env, actual, this);
2271
- positive.not = new (this.getMatchersClass_())(this.env, actual, this, true);
2272
- return positive;
2273
- };
2110
+ getJasmineRequireObj().toHaveBeenCalledWith = function(j$) {
2274
2111
 
2275
- /**
2276
- * Waits a fixed time period before moving to the next block.
2277
- *
2278
- * @deprecated Use waitsFor() instead
2279
- * @param {Number} timeout milliseconds to wait
2280
- */
2281
- jasmine.Spec.prototype.waits = function(timeout) {
2282
- var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this);
2283
- this.addToQueue(waitsFunc);
2284
- return this;
2285
- };
2112
+ function toHaveBeenCalledWith(util) {
2113
+ return {
2114
+ compare: function() {
2115
+ var args = Array.prototype.slice.call(arguments, 0),
2116
+ actual = args[0],
2117
+ expectedArgs = args.slice(1);
2286
2118
 
2287
- /**
2288
- * Waits for the latchFunction to return true before proceeding to the next block.
2289
- *
2290
- * @param {Function} latchFunction
2291
- * @param {String} optional_timeoutMessage
2292
- * @param {Number} optional_timeout
2293
- */
2294
- jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) {
2295
- var latchFunction_ = null;
2296
- var optional_timeoutMessage_ = null;
2297
- var optional_timeout_ = null;
2298
-
2299
- for (var i = 0; i < arguments.length; i++) {
2300
- var arg = arguments[i];
2301
- switch (typeof arg) {
2302
- case 'function':
2303
- latchFunction_ = arg;
2304
- break;
2305
- case 'string':
2306
- optional_timeoutMessage_ = arg;
2307
- break;
2308
- case 'number':
2309
- optional_timeout_ = arg;
2310
- break;
2311
- }
2119
+ if (!j$.isSpy(actual)) {
2120
+ throw new Error('Expected a spy, but got ' + j$.pp(actual) + '.');
2121
+ }
2122
+
2123
+ return {
2124
+ pass: util.contains(actual.calls.allArgs(), expectedArgs)
2125
+ };
2126
+ },
2127
+ message: function(actual) {
2128
+ return {
2129
+ affirmative: "Expected spy " + actual.and.identity() + " to have been called.",
2130
+ negative: "Expected spy " + actual.and.identity() + " not to have been called."
2131
+ };
2132
+ }
2133
+ };
2312
2134
  }
2313
2135
 
2314
- var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this);
2315
- this.addToQueue(waitsForFunc);
2316
- return this;
2136
+ return toHaveBeenCalledWith;
2317
2137
  };
2318
2138
 
2319
- jasmine.Spec.prototype.fail = function (e) {
2320
- var expectationResult = new jasmine.ExpectationResult({
2321
- passed: false,
2322
- message: e ? jasmine.util.formatException(e) : 'Exception',
2323
- trace: { stack: e.stack }
2324
- });
2325
- this.results_.addResult(expectationResult);
2326
- };
2139
+ getJasmineRequireObj().toMatch = function() {
2327
2140
 
2328
- jasmine.Spec.prototype.getMatchersClass_ = function() {
2329
- return this.matchersClass || this.env.matchersClass;
2330
- };
2141
+ function toMatch() {
2142
+ return {
2143
+ compare: function(actual, expected) {
2144
+ var regexp = new RegExp(expected);
2331
2145
 
2332
- jasmine.Spec.prototype.addMatchers = function(matchersPrototype) {
2333
- var parent = this.getMatchersClass_();
2334
- var newMatchersClass = function() {
2335
- parent.apply(this, arguments);
2336
- };
2337
- jasmine.util.inherit(newMatchersClass, parent);
2338
- jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass);
2339
- this.matchersClass = newMatchersClass;
2340
- };
2146
+ return {
2147
+ pass: regexp.test(actual)
2148
+ };
2149
+ }
2150
+ };
2151
+ }
2341
2152
 
2342
- jasmine.Spec.prototype.finishCallback = function() {
2343
- this.env.reporter.reportSpecResults(this);
2153
+ return toMatch;
2344
2154
  };
2345
2155
 
2346
- jasmine.Spec.prototype.finish = function(onComplete) {
2347
- this.removeAllSpies();
2348
- this.finishCallback();
2349
- if (onComplete) {
2350
- onComplete();
2351
- }
2352
- };
2156
+ getJasmineRequireObj().toThrow = function(j$) {
2353
2157
 
2354
- jasmine.Spec.prototype.after = function(doAfter) {
2355
- if (this.queue.isRunning()) {
2356
- this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
2357
- } else {
2358
- this.afterCallbacks.unshift(doAfter);
2359
- }
2360
- };
2158
+ function toThrow(util) {
2159
+ return {
2160
+ compare: function(actual, expected) {
2161
+ var result = { pass: false },
2162
+ threw = false,
2163
+ thrown;
2361
2164
 
2362
- jasmine.Spec.prototype.execute = function(onComplete) {
2363
- var spec = this;
2364
- if (!spec.env.specFilter(spec)) {
2365
- spec.results_.skipped = true;
2366
- spec.finish(onComplete);
2367
- return;
2368
- }
2165
+ if (typeof actual != "function") {
2166
+ throw new Error("Actual is not a Function");
2167
+ }
2369
2168
 
2370
- this.env.reporter.reportSpecStarting(this);
2169
+ try {
2170
+ actual();
2171
+ } catch (e) {
2172
+ threw = true;
2173
+ thrown = e;
2174
+ }
2371
2175
 
2372
- spec.env.currentSpec = spec;
2176
+ if (!threw) {
2177
+ result.message = "Expected function to throw an exception.";
2178
+ return result;
2179
+ }
2373
2180
 
2374
- spec.addBeforesAndAftersToQueue();
2181
+ if (arguments.length == 1) {
2182
+ result.pass = true;
2183
+ result.message = "Expected function not to throw, but it threw " + j$.pp(thrown) + ".";
2375
2184
 
2376
- spec.queue.start(function () {
2377
- spec.finish(onComplete);
2378
- });
2379
- };
2185
+ return result;
2186
+ }
2380
2187
 
2381
- jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
2382
- var runner = this.env.currentRunner();
2383
- var i;
2188
+ if (util.equals(thrown, expected)) {
2189
+ result.pass = true;
2190
+ result.message = "Expected function not to throw " + j$.pp(expected) + ".";
2191
+ } else {
2192
+ result.message = "Expected function to throw " + j$.pp(expected) + ", but it threw " + j$.pp(thrown) + ".";
2193
+ }
2384
2194
 
2385
- for (var suite = this.suite; suite; suite = suite.parentSuite) {
2386
- for (i = 0; i < suite.before_.length; i++) {
2387
- this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this));
2388
- }
2389
- }
2390
- for (i = 0; i < runner.before_.length; i++) {
2391
- this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
2392
- }
2393
- for (i = 0; i < this.afterCallbacks.length; i++) {
2394
- this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
2395
- }
2396
- for (suite = this.suite; suite; suite = suite.parentSuite) {
2397
- for (i = 0; i < suite.after_.length; i++) {
2398
- this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
2399
- }
2400
- }
2401
- for (i = 0; i < runner.after_.length; i++) {
2402
- this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
2195
+ return result;
2196
+ }
2197
+ };
2403
2198
  }
2404
- };
2405
2199
 
2406
- jasmine.Spec.prototype.explodes = function() {
2407
- throw 'explodes function should not have been called';
2200
+ return toThrow;
2408
2201
  };
2409
2202
 
2410
- jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) {
2411
- if (obj == jasmine.undefined) {
2412
- throw "spyOn could not find an object to spy upon for " + methodName + "()";
2413
- }
2414
-
2415
- if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) {
2416
- throw methodName + '() method does not exist';
2417
- }
2203
+ getJasmineRequireObj().toThrowError = function(j$) {
2204
+ function toThrowError (util) {
2205
+ return {
2206
+ compare: function(actual) {
2207
+ var threw = false,
2208
+ thrown,
2209
+ errorType,
2210
+ message,
2211
+ regexp,
2212
+ name,
2213
+ constructorName;
2418
2214
 
2419
- if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) {
2420
- throw new Error(methodName + ' has already been spied upon');
2421
- }
2215
+ if (typeof actual != "function") {
2216
+ throw new Error("Actual is not a Function");
2217
+ }
2422
2218
 
2423
- var spyObj = jasmine.createSpy(methodName);
2219
+ extractExpectedParams.apply(null, arguments);
2424
2220
 
2425
- this.spies_.push(spyObj);
2426
- spyObj.baseObj = obj;
2427
- spyObj.methodName = methodName;
2428
- spyObj.originalValue = obj[methodName];
2221
+ try {
2222
+ actual();
2223
+ } catch (e) {
2224
+ threw = true;
2225
+ thrown = e;
2226
+ }
2429
2227
 
2430
- obj[methodName] = spyObj;
2228
+ if (!threw) {
2229
+ return fail("Expected function to throw an Error.");
2230
+ }
2431
2231
 
2432
- return spyObj;
2433
- };
2232
+ if (!(thrown instanceof Error)) {
2233
+ return fail("Expected function to throw an Error, but it threw " + thrown + ".");
2234
+ }
2434
2235
 
2435
- jasmine.Spec.prototype.removeAllSpies = function() {
2436
- for (var i = 0; i < this.spies_.length; i++) {
2437
- var spy = this.spies_[i];
2438
- spy.baseObj[spy.methodName] = spy.originalValue;
2439
- }
2440
- this.spies_ = [];
2441
- };
2236
+ if (arguments.length == 1) {
2237
+ return pass("Expected function not to throw an Error, but it threw " + fnNameFor(thrown) + ".");
2238
+ }
2442
2239
 
2443
- /**
2444
- * Internal representation of a Jasmine suite.
2445
- *
2446
- * @constructor
2447
- * @param {jasmine.Env} env
2448
- * @param {String} description
2449
- * @param {Function} specDefinitions
2450
- * @param {jasmine.Suite} parentSuite
2451
- */
2452
- jasmine.Suite = function(env, description, specDefinitions, parentSuite) {
2453
- var self = this;
2454
- self.id = env.nextSuiteId ? env.nextSuiteId() : null;
2455
- self.description = description;
2456
- self.queue = new jasmine.Queue(env);
2457
- self.parentSuite = parentSuite;
2458
- self.env = env;
2459
- self.before_ = [];
2460
- self.after_ = [];
2461
- self.children_ = [];
2462
- self.suites_ = [];
2463
- self.specs_ = [];
2464
- };
2240
+ if (errorType) {
2241
+ name = fnNameFor(errorType);
2242
+ constructorName = fnNameFor(thrown.constructor);
2243
+ }
2465
2244
 
2466
- jasmine.Suite.prototype.getFullName = function() {
2467
- var fullName = this.description;
2468
- for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
2469
- fullName = parentSuite.description + ' ' + fullName;
2470
- }
2471
- return fullName;
2472
- };
2245
+ if (errorType && message) {
2246
+ if (thrown.constructor == errorType && util.equals(thrown.message, message)) {
2247
+ return pass("Expected function not to throw " + name + " with message \"" + message + "\".");
2248
+ } else {
2249
+ return fail("Expected function to throw " + name + " with message \"" + message +
2250
+ "\", but it threw " + constructorName + " with message \"" + thrown.message + "\".");
2251
+ }
2252
+ }
2473
2253
 
2474
- jasmine.Suite.prototype.finish = function(onComplete) {
2475
- this.env.reporter.reportSuiteResults(this);
2476
- this.finished = true;
2477
- if (typeof(onComplete) == 'function') {
2478
- onComplete();
2479
- }
2480
- };
2254
+ if (errorType && regexp) {
2255
+ if (thrown.constructor == errorType && regexp.test(thrown.message)) {
2256
+ return pass("Expected function not to throw " + name + " with message matching " + regexp + ".");
2257
+ } else {
2258
+ return fail("Expected function to throw " + name + " with message matching " + regexp +
2259
+ ", but it threw " + constructorName + " with message \"" + thrown.message + "\".");
2260
+ }
2261
+ }
2481
2262
 
2482
- jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) {
2483
- beforeEachFunction.typeName = 'beforeEach';
2484
- this.before_.unshift(beforeEachFunction);
2485
- };
2263
+ if (errorType) {
2264
+ if (thrown.constructor == errorType) {
2265
+ return pass("Expected function not to throw " + name + ".");
2266
+ } else {
2267
+ return fail("Expected function to throw " + name + ", but it threw " + constructorName + ".");
2268
+ }
2269
+ }
2486
2270
 
2487
- jasmine.Suite.prototype.afterEach = function(afterEachFunction) {
2488
- afterEachFunction.typeName = 'afterEach';
2489
- this.after_.unshift(afterEachFunction);
2490
- };
2271
+ if (message) {
2272
+ if (thrown.message == message) {
2273
+ return pass("Expected function not to throw an exception with message " + j$.pp(message) + ".");
2274
+ } else {
2275
+ return fail("Expected function to throw an exception with message " + j$.pp(message) +
2276
+ ", but it threw an exception with message " + j$.pp(thrown.message) + ".");
2277
+ }
2278
+ }
2491
2279
 
2492
- jasmine.Suite.prototype.results = function() {
2493
- return this.queue.results();
2494
- };
2280
+ if (regexp) {
2281
+ if (regexp.test(thrown.message)) {
2282
+ return pass("Expected function not to throw an exception with a message matching " + j$.pp(regexp) + ".");
2283
+ } else {
2284
+ return fail("Expected function to throw an exception with a message matching " + j$.pp(regexp) +
2285
+ ", but it threw an exception with message " + j$.pp(thrown.message) + ".");
2286
+ }
2287
+ }
2495
2288
 
2496
- jasmine.Suite.prototype.add = function(suiteOrSpec) {
2497
- this.children_.push(suiteOrSpec);
2498
- if (suiteOrSpec instanceof jasmine.Suite) {
2499
- this.suites_.push(suiteOrSpec);
2500
- this.env.currentRunner().addSuite(suiteOrSpec);
2501
- } else {
2502
- this.specs_.push(suiteOrSpec);
2503
- }
2504
- this.queue.add(suiteOrSpec);
2505
- };
2289
+ function fnNameFor(func) {
2290
+ return func.name || func.toString().match(/^\s*function\s*(\w*)\s*\(/)[1];
2291
+ }
2506
2292
 
2507
- jasmine.Suite.prototype.specs = function() {
2508
- return this.specs_;
2509
- };
2293
+ function pass(notMessage) {
2294
+ return {
2295
+ pass: true,
2296
+ message: notMessage
2297
+ };
2298
+ }
2510
2299
 
2511
- jasmine.Suite.prototype.suites = function() {
2512
- return this.suites_;
2513
- };
2300
+ function fail(message) {
2301
+ return {
2302
+ pass: false,
2303
+ message: message
2304
+ };
2305
+ }
2514
2306
 
2515
- jasmine.Suite.prototype.children = function() {
2516
- return this.children_;
2517
- };
2307
+ function extractExpectedParams() {
2308
+ if (arguments.length == 1) {
2309
+ return;
2310
+ }
2518
2311
 
2519
- jasmine.Suite.prototype.execute = function(onComplete) {
2520
- var self = this;
2521
- this.queue.start(function () {
2522
- self.finish(onComplete);
2523
- });
2524
- };
2525
- jasmine.WaitsBlock = function(env, timeout, spec) {
2526
- this.timeout = timeout;
2527
- jasmine.Block.call(this, env, null, spec);
2528
- };
2312
+ if (arguments.length == 2) {
2313
+ var expected = arguments[1];
2529
2314
 
2530
- jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block);
2315
+ if (expected instanceof RegExp) {
2316
+ regexp = expected;
2317
+ } else if (typeof expected == "string") {
2318
+ message = expected;
2319
+ } else if (checkForAnErrorType(expected)) {
2320
+ errorType = expected;
2321
+ }
2531
2322
 
2532
- jasmine.WaitsBlock.prototype.execute = function (onComplete) {
2533
- if (jasmine.VERBOSE) {
2534
- this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...');
2535
- }
2536
- this.env.setTimeout(function () {
2537
- onComplete();
2538
- }, this.timeout);
2539
- };
2540
- /**
2541
- * A block which waits for some condition to become true, with timeout.
2542
- *
2543
- * @constructor
2544
- * @extends jasmine.Block
2545
- * @param {jasmine.Env} env The Jasmine environment.
2546
- * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true.
2547
- * @param {Function} latchFunction A function which returns true when the desired condition has been met.
2548
- * @param {String} message The message to display if the desired condition hasn't been met within the given time period.
2549
- * @param {jasmine.Spec} spec The Jasmine spec.
2550
- */
2551
- jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) {
2552
- this.timeout = timeout || env.defaultTimeoutInterval;
2553
- this.latchFunction = latchFunction;
2554
- this.message = message;
2555
- this.totalTimeSpentWaitingForLatch = 0;
2556
- jasmine.Block.call(this, env, null, spec);
2557
- };
2558
- jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block);
2323
+ if (!(errorType || message || regexp)) {
2324
+ throw new Error("Expected is not an Error, string, or RegExp.");
2325
+ }
2326
+ } else {
2327
+ if (checkForAnErrorType(arguments[1])) {
2328
+ errorType = arguments[1];
2329
+ } else {
2330
+ throw new Error("Expected error type is not an Error.");
2331
+ }
2332
+
2333
+ if (arguments[2] instanceof RegExp) {
2334
+ regexp = arguments[2];
2335
+ } else if (typeof arguments[2] == "string") {
2336
+ message = arguments[2];
2337
+ } else {
2338
+ throw new Error("Expected error message is not a string or RegExp.");
2339
+ }
2340
+ }
2341
+ }
2559
2342
 
2560
- jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10;
2343
+ function checkForAnErrorType(type) {
2344
+ if (typeof type !== "function") {
2345
+ return false;
2346
+ }
2561
2347
 
2562
- jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
2563
- if (jasmine.VERBOSE) {
2564
- this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen'));
2565
- }
2566
- var latchFunctionResult;
2567
- try {
2568
- latchFunctionResult = this.latchFunction.apply(this.spec);
2569
- } catch (e) {
2570
- this.spec.fail(e);
2571
- onComplete();
2572
- return;
2348
+ var Surrogate = function() {};
2349
+ Surrogate.prototype = type.prototype;
2350
+ return (new Surrogate()) instanceof Error;
2351
+ }
2352
+ }
2353
+ };
2573
2354
  }
2574
2355
 
2575
- if (latchFunctionResult) {
2576
- onComplete();
2577
- } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) {
2578
- var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen');
2579
- this.spec.fail({
2580
- name: 'timeout',
2581
- message: message
2582
- });
2583
-
2584
- this.abort = true;
2585
- onComplete();
2586
- } else {
2587
- this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT;
2588
- var self = this;
2589
- this.env.setTimeout(function() {
2590
- self.execute(onComplete);
2591
- }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT);
2592
- }
2356
+ return toThrowError;
2593
2357
  };
2594
2358
 
2595
- jasmine.version_= {
2596
- "major": 1,
2597
- "minor": 3,
2598
- "build": 1,
2599
- "revision": 1354556913
2600
- };
2359
+ getJasmineRequireObj().version = function() {
2360
+ return "2.0.0-rc2";
2361
+ };