snapdragon 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 060c173490d27d0726bb3e47791d9aeae29ed196
4
- data.tar.gz: 2dd3df4162edd3d0fffb0862651c1cfb8a07c2d9
3
+ metadata.gz: 245a1080431376a79728953a841a85f5a2df4eae
4
+ data.tar.gz: a71b35a34b7edb62a612ab8fe69a6cfb792ff485
5
5
  SHA512:
6
- metadata.gz: 168b20c3b123901008ec0cbbbdd3320f44a63d3ce3eb3b3df2124d8b0eb20b9f22198e8e6fdcedfe756843d83ba3f06f58f3a0a663d24f8d565e299a0b6458fd
7
- data.tar.gz: 3d169461aaa8517e85c8a98d8e82c84551aff91529480d0adb02b92d2a3ee6bbb11227c0ebd0d8dc0eb79e60550355e0ddcbfdf97fd439e06f8e15a8fa7c8edc
6
+ metadata.gz: 320be3c918fbbcd98da4958b7fa86fb4cbad056a0cfcdd970dbb23302278cc73687138e509056dcc1ad7d46824c88ebe8c7d7c3b032e488b6ff36f5b94ac60f7
7
+ data.tar.gz: 4da5eaacb64b3adbfa400fc848110a3f5c92f27e5189fbabd4eea3fdd96e03f6c1745ec8e2ed9cbdb7fba6097a53e7e2fe4c5fd1f5b009993631b9d6538599dd
@@ -0,0 +1,129 @@
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
+ // Jasmine boot.js for browser runners - exposes external/global interface, builds the Jasmine environment and executes it.
24
+ (function() {
25
+ window.jasmine = jasmineRequire.core(jasmineRequire);
26
+ jasmineRequire.html(jasmine);
27
+
28
+ var env = jasmine.getEnv();
29
+
30
+ var jasmineInterface = {
31
+ describe: function(description, specDefinitions) {
32
+ return env.describe(description, specDefinitions);
33
+ },
34
+
35
+ xdescribe: function(description, specDefinitions) {
36
+ return env.xdescribe(description, specDefinitions);
37
+ },
38
+
39
+ it: function(desc, func) {
40
+ return env.it(desc, func);
41
+ },
42
+
43
+ xit: function(desc, func) {
44
+ return env.xit(desc, func);
45
+ },
46
+
47
+ beforeEach: function(beforeEachFunction) {
48
+ return env.beforeEach(beforeEachFunction);
49
+ },
50
+
51
+ afterEach: function(afterEachFunction) {
52
+ return env.afterEach(afterEachFunction);
53
+ },
54
+
55
+ expect: function(actual) {
56
+ return env.expect(actual);
57
+ },
58
+
59
+ pending: function() {
60
+ return env.pending();
61
+ },
62
+
63
+ addMatchers: function(matchers) {
64
+ return env.addMatchers(matchers);
65
+ },
66
+
67
+ spyOn: function(obj, methodName) {
68
+ return env.spyOn(obj, methodName);
69
+ },
70
+
71
+ clock: env.clock,
72
+ setTimeout: env.clock.setTimeout,
73
+ clearTimeout: env.clock.clearTimeout,
74
+ setInterval: env.clock.setInterval,
75
+ clearInterval: env.clock.clearInterval,
76
+
77
+ jsApiReporter: new jasmine.JsApiReporter(jasmine)
78
+ };
79
+
80
+ if (typeof window == "undefined" && typeof exports == "object") {
81
+ extend(exports, jasmineInterface);
82
+ } else {
83
+ extend(window, jasmineInterface);
84
+ }
85
+
86
+ var queryString = new jasmine.QueryString({
87
+ getWindowLocation: function() { return window.location; }
88
+ });
89
+
90
+ // TODO: move all of catching to raise so we don't break our brains
91
+ var catchingExceptions = queryString.getParam("catch");
92
+ env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
93
+
94
+ var htmlReporter = new jasmine.HtmlReporter({
95
+ env: env,
96
+ queryString: queryString,
97
+ onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
98
+ getContainer: function() { return document.body; },
99
+ createElement: function() { return document.createElement.apply(document, arguments); },
100
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
101
+ });
102
+
103
+ env.addReporter(jasmineInterface.jsApiReporter);
104
+ env.addReporter(htmlReporter);
105
+
106
+ var specFilter = new jasmine.HtmlSpecFilter({
107
+ filterString: function() { return queryString.getParam("spec"); }
108
+ });
109
+
110
+ env.specFilter = function(spec) {
111
+ return specFilter.matches(spec.getFullName());
112
+ };
113
+
114
+ var currentWindowOnload = window.onload;
115
+
116
+ window.onload = function() {
117
+ if (currentWindowOnload) {
118
+ currentWindowOnload();
119
+ }
120
+ htmlReporter.initialize();
121
+ env.execute();
122
+ };
123
+
124
+ function extend(destination, source) {
125
+ for (var property in source) destination[property] = source[property];
126
+ return destination;
127
+ }
128
+
129
+ }());
@@ -0,0 +1,107 @@
1
+ // Jasmine boot.js for browser runners - exposes external/global interface, builds the Jasmine environment and executes it.
2
+ (function() {
3
+ window.jasmine = jasmineRequire.core(jasmineRequire);
4
+ jasmineRequire.html(jasmine);
5
+
6
+ var env = jasmine.getEnv();
7
+
8
+ var jasmineInterface = {
9
+ describe: function(description, specDefinitions) {
10
+ return env.describe(description, specDefinitions);
11
+ },
12
+
13
+ xdescribe: function(description, specDefinitions) {
14
+ return env.xdescribe(description, specDefinitions);
15
+ },
16
+
17
+ it: function(desc, func) {
18
+ return env.it(desc, func);
19
+ },
20
+
21
+ xit: function(desc, func) {
22
+ return env.xit(desc, func);
23
+ },
24
+
25
+ beforeEach: function(beforeEachFunction) {
26
+ return env.beforeEach(beforeEachFunction);
27
+ },
28
+
29
+ afterEach: function(afterEachFunction) {
30
+ return env.afterEach(afterEachFunction);
31
+ },
32
+
33
+ expect: function(actual) {
34
+ return env.expect(actual);
35
+ },
36
+
37
+ pending: function() {
38
+ return env.pending();
39
+ },
40
+
41
+ addMatchers: function(matchers) {
42
+ return env.addMatchers(matchers);
43
+ },
44
+
45
+ spyOn: function(obj, methodName) {
46
+ return env.spyOn(obj, methodName);
47
+ },
48
+
49
+ clock: env.clock,
50
+ setTimeout: env.clock.setTimeout,
51
+ clearTimeout: env.clock.clearTimeout,
52
+ setInterval: env.clock.setInterval,
53
+ clearInterval: env.clock.clearInterval,
54
+
55
+ jsApiReporter: new jasmine.JsApiReporter(jasmine)
56
+ };
57
+
58
+ if (typeof window == "undefined" && typeof exports == "object") {
59
+ extend(exports, jasmineInterface);
60
+ } else {
61
+ extend(window, jasmineInterface);
62
+ }
63
+
64
+ var queryString = new jasmine.QueryString({
65
+ getWindowLocation: function() { return window.location; }
66
+ });
67
+
68
+ // TODO: move all of catching to raise so we don't break our brains
69
+ var catchingExceptions = queryString.getParam("catch");
70
+ env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions);
71
+
72
+ var htmlReporter = new jasmine.HtmlReporter({
73
+ env: env,
74
+ queryString: queryString,
75
+ onRaiseExceptionsClick: function() { queryString.setParam("catch", !env.catchingExceptions()); },
76
+ getContainer: function() { return document.body; },
77
+ createElement: function() { return document.createElement.apply(document, arguments); },
78
+ createTextNode: function() { return document.createTextNode.apply(document, arguments); }
79
+ });
80
+
81
+ env.addReporter(jasmineInterface.jsApiReporter);
82
+ env.addReporter(htmlReporter);
83
+
84
+ var specFilter = new jasmine.HtmlSpecFilter({
85
+ filterString: function() { return queryString.getParam("spec"); }
86
+ });
87
+
88
+ env.specFilter = function(spec) {
89
+ return specFilter.matches(spec.getFullName());
90
+ };
91
+
92
+ var currentWindowOnload = window.onload;
93
+
94
+ window.onload = function() {
95
+ if (currentWindowOnload) {
96
+ currentWindowOnload();
97
+ }
98
+ htmlReporter.initialize();
99
+ env.execute();
100
+ };
101
+
102
+ function extend(destination, source) {
103
+ for (var property in source) destination[property] = source[property];
104
+ return destination;
105
+ }
106
+
107
+ }());
@@ -0,0 +1,58 @@
1
+ describe("Player", function() {
2
+ var player;
3
+ var song;
4
+
5
+ beforeEach(function() {
6
+ player = new Player();
7
+ song = new Song();
8
+ });
9
+
10
+ it("should be able to play a Song", function() {
11
+ player.play(song);
12
+ expect(player.currentlyPlayingSong).toEqual(song);
13
+
14
+ //demonstrates use of custom matcher
15
+ expect(player).toBePlaying(song);
16
+ });
17
+
18
+ describe("when song has been paused", function() {
19
+ beforeEach(function() {
20
+ player.play(song);
21
+ player.pause();
22
+ });
23
+
24
+ it("should indicate that the song is currently paused", function() {
25
+ expect(player.isPlaying).toBeFalsy();
26
+
27
+ // demonstrates use of 'not' with a custom matcher
28
+ expect(player).not.toBePlaying(song);
29
+ });
30
+
31
+ it("should be possible to resume", function() {
32
+ player.resume();
33
+ expect(player.isPlaying).toBeTruthy();
34
+ expect(player.currentlyPlayingSong).toEqual(song);
35
+ });
36
+ });
37
+
38
+ // demonstrates use of spies to intercept and test method calls
39
+ it("tells the current song if the user has made it a favorite", function() {
40
+ spyOn(song, 'persistFavoriteStatus');
41
+
42
+ player.play(song);
43
+ player.makeFavorite();
44
+
45
+ expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
46
+ });
47
+
48
+ //demonstrates use of expected exceptions
49
+ describe("#resume", function() {
50
+ it("should throw an exception if song is already playing", function() {
51
+ player.play(song);
52
+
53
+ expect(function() {
54
+ player.resume();
55
+ }).toThrow("song is already playing");
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,9 @@
1
+ beforeEach(function() {
2
+ addMatchers({
3
+ toBePlaying: function(expectedSong) {
4
+ var player = this.actual;
5
+ return player.currentlyPlayingSong === expectedSong &&
6
+ player.isPlaying;
7
+ }
8
+ });
9
+ });
@@ -0,0 +1,22 @@
1
+ function Player() {
2
+ }
3
+ Player.prototype.play = function(song) {
4
+ this.currentlyPlayingSong = song;
5
+ this.isPlaying = true;
6
+ };
7
+
8
+ Player.prototype.pause = function() {
9
+ this.isPlaying = false;
10
+ };
11
+
12
+ Player.prototype.resume = function() {
13
+ if (this.isPlaying) {
14
+ throw new Error("song is already playing");
15
+ }
16
+
17
+ this.isPlaying = true;
18
+ };
19
+
20
+ Player.prototype.makeFavorite = function() {
21
+ this.currentlyPlayingSong.persistFavoriteStatus(true);
22
+ };
@@ -0,0 +1,7 @@
1
+ function Song() {
2
+ }
3
+
4
+ Song.prototype.persistFavoriteStatus = function(value) {
5
+ // something complicated
6
+ throw new Error("not yet implemented");
7
+ };
@@ -0,0 +1,344 @@
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
+ jasmineRequire.html = function(j$) {
24
+ j$.ResultsNode = jasmineRequire.ResultsNode();
25
+ j$.HtmlReporter = jasmineRequire.HtmlReporter();
26
+ j$.QueryString = jasmineRequire.QueryString();
27
+ j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
28
+ };
29
+ jasmineRequire.HtmlReporter = function() {
30
+ function HtmlReporter(options) {
31
+ var env = options.env || {},
32
+ getContainer = options.getContainer,
33
+ createElement = options.createElement,
34
+ createTextNode = options.createTextNode,
35
+ onRaiseExceptionsClick = options.onRaiseExceptionsClick,
36
+ results = [],
37
+ specsExecuted = 0,
38
+ failureCount = 0,
39
+ pendingSpecCount = 0,
40
+ htmlReporterMain,
41
+ symbols;
42
+
43
+ this.initialize = function() {
44
+ htmlReporterMain = createDom("div", {className: "html-reporter"},
45
+ createDom("div", {className: "banner"},
46
+ createDom("span", {className: "title"}, "Jasmine"),
47
+ createDom("span", {className: "version"}, jasmine.version)
48
+ ),
49
+ createDom("ul", {className: "symbol-summary"}),
50
+ createDom("div", {className: "alert"}),
51
+ createDom("div", {className: "results"},
52
+ createDom("div", {className: "failures"})
53
+ )
54
+ );
55
+ getContainer().appendChild(htmlReporterMain);
56
+
57
+ symbols = find(".symbol-summary");
58
+ };
59
+
60
+ var totalSpecsDefined;
61
+ this.jasmineStarted = function(options) {
62
+ totalSpecsDefined = options.totalSpecsDefined || 0;
63
+ };
64
+
65
+ var summary = createDom("div", {className: "summary"});
66
+
67
+ var topResults = new jasmine.ResultsNode({}, "", null),
68
+ currentParent = topResults;
69
+
70
+ this.suiteStarted = function(result) {
71
+ currentParent.addChild(result, "suite");
72
+ currentParent = currentParent.last();
73
+ };
74
+
75
+ this.suiteDone = function(result) {
76
+ if (currentParent == topResults) {
77
+ return;
78
+ }
79
+
80
+ currentParent = currentParent.parent;
81
+ };
82
+
83
+ this.specStarted = function(result) {
84
+ currentParent.addChild(result, "spec");
85
+ };
86
+
87
+ var failures = [];
88
+ this.specDone = function(result) {
89
+ if (result.status != "disabled") {
90
+ specsExecuted++;
91
+ }
92
+
93
+ symbols.appendChild(createDom("li", {
94
+ className: result.status,
95
+ id: "spec_" + result.id,
96
+ title: result.fullName}
97
+ ));
98
+
99
+ if (result.status == "failed") {
100
+ failureCount++;
101
+
102
+ var failure =
103
+ createDom("div", {className: "spec-detail failed"},
104
+ createDom("a", {className: "description", title: result.fullName, href: specHref(result)}, result.fullName),
105
+ createDom("div", {className: "messages"})
106
+ );
107
+ var messages = failure.childNodes[1];
108
+
109
+ for (var i = 0; i < result.failedExpectations.length; i++) {
110
+ var expectation = result.failedExpectations[i];
111
+ messages.appendChild(createDom("div", {className: "result-message"}, expectation.message));
112
+ messages.appendChild(createDom("div", {className: "stack-trace"}, expectation.stack));
113
+ }
114
+
115
+ failures.push(failure);
116
+ }
117
+
118
+ if (result.status == "pending") {
119
+ pendingSpecCount++;
120
+ }
121
+ };
122
+
123
+ this.jasmineDone = function(options) {
124
+ var banner = find(".banner");
125
+ banner.appendChild(createDom("span", {className: "duration"}, "finished in " + options.executionTime / 1000 + "s"));
126
+
127
+ var alert = find(".alert");
128
+
129
+ alert.appendChild(createDom("span", { className: "exceptions" },
130
+ createDom("label", { className: "label", 'for': "raise-exceptions" }, "raise exceptions"),
131
+ createDom("input", {
132
+ className: "raise",
133
+ id: "raise-exceptions",
134
+ type: "checkbox"
135
+ })
136
+ ));
137
+ var checkbox = find("input");
138
+
139
+ checkbox.checked = !env.catchingExceptions();
140
+ checkbox.onclick = onRaiseExceptionsClick;
141
+
142
+ if (specsExecuted < totalSpecsDefined) {
143
+ var skippedMessage = "Ran " + specsExecuted + " of " + totalSpecsDefined + " specs - run all";
144
+ alert.appendChild(
145
+ createDom("span", {className: "bar skipped"},
146
+ createDom("a", {href: "?", title: "Run all specs"}, skippedMessage)
147
+ )
148
+ );
149
+ }
150
+ var statusBarMessage = "" + pluralize("spec", specsExecuted) + ", " + pluralize("failure", failureCount);
151
+ if (pendingSpecCount) { statusBarMessage += ", " + pluralize("pending spec", pendingSpecCount); }
152
+
153
+ var statusBarClassName = "bar " + ((failureCount > 0) ? "failed" : "passed");
154
+ alert.appendChild(createDom("span", {className: statusBarClassName}, statusBarMessage));
155
+
156
+ var results = find(".results");
157
+ results.appendChild(summary);
158
+
159
+ summaryList(topResults, summary);
160
+
161
+ function summaryList(resultsTree, domParent) {
162
+ var specListNode;
163
+ for (var i = 0; i < resultsTree.children.length; i++) {
164
+ var resultNode = resultsTree.children[i];
165
+ if (resultNode.type == "suite") {
166
+ var suiteListNode = createDom("ul", {className: "suite", id: "suite-" + resultNode.result.id},
167
+ createDom("li", {className: "suite-detail"},
168
+ createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
169
+ )
170
+ );
171
+
172
+ summaryList(resultNode, suiteListNode);
173
+ domParent.appendChild(suiteListNode);
174
+ }
175
+ if (resultNode.type == "spec") {
176
+ if (domParent.getAttribute("class") != "specs") {
177
+ specListNode = createDom("ul", {className: "specs"});
178
+ domParent.appendChild(specListNode);
179
+ }
180
+ specListNode.appendChild(
181
+ createDom("li", {
182
+ className: resultNode.result.status,
183
+ id: "spec-" + resultNode.result.id
184
+ },
185
+ createDom("a", {href: specHref(resultNode.result)}, resultNode.result.description)
186
+ )
187
+ );
188
+ }
189
+ }
190
+ }
191
+
192
+ if (failures.length) {
193
+ alert.appendChild(
194
+ createDom('span', {className: "menu bar spec-list"},
195
+ createDom("span", {}, "Spec List | "),
196
+ createDom('a', {className: "failures-menu", href: "#"}, "Failures")));
197
+ alert.appendChild(
198
+ createDom('span', {className: "menu bar failure-list"},
199
+ createDom('a', {className: "spec-list-menu", href: "#"}, "Spec List"),
200
+ createDom("span", {}, " | Failures ")));
201
+
202
+ find(".failures-menu").onclick = function() {
203
+ setMenuModeTo('failure-list');
204
+ };
205
+ find(".spec-list-menu").onclick = function() {
206
+ setMenuModeTo('spec-list');
207
+ };
208
+
209
+ setMenuModeTo('failure-list');
210
+
211
+ var failureNode = find(".failures");
212
+ for (var i = 0; i < failures.length; i++) {
213
+ failureNode.appendChild(failures[i]);
214
+ }
215
+ }
216
+ };
217
+
218
+ return this;
219
+
220
+ function find(selector) {
221
+ return getContainer().querySelector(selector);
222
+ }
223
+
224
+ function createDom(type, attrs, childrenVarArgs) {
225
+ var el = createElement(type);
226
+
227
+ for (var i = 2; i < arguments.length; i++) {
228
+ var child = arguments[i];
229
+
230
+ if (typeof child === 'string') {
231
+ el.appendChild(createTextNode(child));
232
+ } else {
233
+ if (child) {
234
+ el.appendChild(child);
235
+ }
236
+ }
237
+ }
238
+
239
+ for (var attr in attrs) {
240
+ if (attr == "className") {
241
+ el[attr] = attrs[attr];
242
+ } else {
243
+ el.setAttribute(attr, attrs[attr]);
244
+ }
245
+ }
246
+
247
+ return el;
248
+ }
249
+
250
+ function pluralize(singular, count) {
251
+ var word = (count == 1 ? singular : singular + "s");
252
+
253
+ return "" + count + " " + word;
254
+ }
255
+
256
+ function specHref(result) {
257
+ return "?spec=" + encodeURIComponent(result.fullName);
258
+ }
259
+
260
+ function setMenuModeTo(mode) {
261
+ htmlReporterMain.setAttribute("class", "html-reporter " + mode);
262
+ }
263
+ }
264
+
265
+ return HtmlReporter;
266
+ };
267
+
268
+ jasmineRequire.HtmlSpecFilter = function() {
269
+ function HtmlSpecFilter(options) {
270
+ var filterPattern = new RegExp(options && options.filterString());
271
+
272
+ this.matches = function(specName) {
273
+ return filterPattern.test(specName);
274
+ };
275
+ }
276
+
277
+ return HtmlSpecFilter;
278
+ };
279
+ jasmineRequire.ResultsNode = function() {
280
+ function ResultsNode(result, type, parent) {
281
+ this.result = result;
282
+ this.type = type;
283
+ this.parent = parent;
284
+
285
+ this.children = [];
286
+
287
+ this.addChild = function(result, type) {
288
+ this.children.push(new ResultsNode(result, type, this));
289
+ };
290
+
291
+ this.last = function() {
292
+ return this.children[this.children.length - 1];
293
+ };
294
+ }
295
+
296
+ return ResultsNode;
297
+ };
298
+ jasmineRequire.QueryString = function() {
299
+ function QueryString(options) {
300
+
301
+ this.setParam = function(key, value) {
302
+ var paramMap = queryStringToParamMap();
303
+ paramMap[key] = value;
304
+ options.getWindowLocation().search = toQueryString(paramMap);
305
+ };
306
+
307
+ this.getParam = function(key) {
308
+ return queryStringToParamMap()[key];
309
+ };
310
+
311
+ return this;
312
+
313
+ function toQueryString(paramMap) {
314
+ var qStrPairs = [];
315
+ for (var prop in paramMap) {
316
+ qStrPairs.push(encodeURIComponent(prop) + "=" + encodeURIComponent(paramMap[prop]));
317
+ }
318
+ return "?" + qStrPairs.join('&');
319
+ }
320
+
321
+ function queryStringToParamMap() {
322
+ var paramStr = options.getWindowLocation().search.substring(1),
323
+ params = [],
324
+ paramMap = {};
325
+
326
+ if (paramStr.length > 0) {
327
+ params = paramStr.split('&');
328
+ for (var i = 0; i < params.length; i++) {
329
+ var p = params[i].split('=');
330
+ var value = decodeURIComponent(p[1]);
331
+ if (value === "true" || value === "false") {
332
+ value = JSON.parse(value);
333
+ }
334
+ paramMap[decodeURIComponent(p[0])] = value;
335
+ }
336
+ }
337
+
338
+ return paramMap;
339
+ }
340
+
341
+ }
342
+
343
+ return QueryString;
344
+ };