qedproject 0.3.0 → 0.3.1

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.
data/bin/qedproject CHANGED
@@ -38,6 +38,10 @@ OptionParser.new do |opts|
38
38
  options[:libs] = libs.split(",").collect{ |f| f.to_sym }
39
39
  end
40
40
 
41
+ opts.on('-r', '--livereload', "Use LiveReload") do
42
+ options[:livereload] = true
43
+ end
44
+
41
45
  opts.on('-o', '--overwrite', "Overwrite existing files with same names") do
42
46
  options[:no_overwrite] = false
43
47
  end
@@ -7,7 +7,7 @@ module QEDProject
7
7
  include QEDProject::Helpers
8
8
 
9
9
  attr_accessor :path, :libs, :coffeescript, :sass, :jammit, :public_dir, :no_overwrite,
10
- :js_path, :css_path, :images_path, :verbose, :testing, :skip_index,
10
+ :js_path, :css_path, :images_path, :verbose, :testing, :skip_index, :livereload,
11
11
  :sorted_libs,
12
12
  :css_assets, :js_assets
13
13
  # convenience method to create a new project.
@@ -24,6 +24,10 @@ module QEDProject
24
24
  File.expand_path("../../../vendor", __FILE__)
25
25
  end
26
26
 
27
+ def uses_jquery?
28
+ self.libs.include?(:jquery)
29
+ end
30
+
27
31
  # Creates a new Project instance.
28
32
  # Options:
29
33
  # :libs : A list of js libraries to include, Can be :backbone, :jquery, :knockout
@@ -81,6 +85,7 @@ module QEDProject
81
85
  self.verbose = options[:verbose]
82
86
  self.testing = options[:testing]
83
87
  self.skip_index = options[:skip_index]
88
+ self.livereload = options[:livereload]
84
89
  self.no_overwrite = options[:no_overwrite] ? true : false
85
90
  end
86
91
 
@@ -93,7 +98,7 @@ module QEDProject
93
98
 
94
99
  # We need a guardfile if the user is using jammit, sass, or coffeescript.
95
100
  def needs_guardfile?
96
- self.jammit || self.sass || self.coffeescript
101
+ self.jammit || self.sass || self.coffeescript || self.livereload
97
102
  end
98
103
 
99
104
  # Only jammit needs a config folder for now.
@@ -123,7 +128,9 @@ module QEDProject
123
128
  mkdir_p File.join(self.path, "spec"), :verbose => self.verbose
124
129
  cp_r File.join(self.vendor_root, "jasmine", "lib"),
125
130
  File.join(self.path, "spec", "lib"), :verbose => self.verbose
126
-
131
+ if self.uses_jquery?
132
+ cp_r File.join(self.vendor_root, "jasmine-jquery", "jasmine-jquery.js"), File.join(self.path, "spec", "lib"), :verbose => self.verbose
133
+ end
127
134
 
128
135
  render_template_to_file "suite.html", File.join(self.path, "spec", "suite.html"), binding
129
136
  if self.coffeescript
@@ -1,3 +1,3 @@
1
1
  module QEDProject
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.1"
3
3
  end
data/templates/Gemfile CHANGED
@@ -1,4 +1,5 @@
1
1
  source 'https://rubygems.org'
2
+ gem 'qedproject'
2
3
  gem 'guard'
3
4
  <% if self.sass -%>
4
5
  gem 'guard-sass'
@@ -9,4 +10,6 @@ gem 'guard-coffeescript'
9
10
  <% if self.jammit -%>
10
11
  gem 'guard-jammit'
11
12
  <% end -%>
13
+ <% if self.livereload -%>
12
14
  gem 'guard-livereload'
15
+ <% end -%>
data/templates/Guardfile CHANGED
@@ -32,8 +32,11 @@ guard 'livereload' do
32
32
  watch(%r{public/.+\.(css|js|html)})
33
33
  <% if self.jammit -%>
34
34
  watch(%r{public/assets/.+\.(css|js|html)})
35
- <% else %>
35
+ <% else -%>
36
36
  watch(%r{public/javascripts/.+\.js})
37
37
  watch(%r{public/stylesheets/.+\.css})
38
38
  <% end -%>
39
+ <% if self.testing -%>
40
+ watch(%r{spec/.+\.(|js|html)})
41
+ <% end -%>
39
42
  end
data/templates/suite.html CHANGED
@@ -2,10 +2,12 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>Jasmine Test Runner</title>
5
- <link rel="stylesheet" type="text/css" href="lib/jasmine-1.0.2/jasmine.css">
6
- <script type="text/javascript" src="lib/jasmine-1.0.2/jasmine.js"></script>
7
- <script type="text/javascript" src="lib/jasmine-1.0.2/jasmine-html.js"></script>
8
-
5
+ <link rel="stylesheet" type="text/css" href="lib/jasmine-1.1.0/jasmine.css">
6
+ <script type="text/javascript" src="lib/jasmine-1.1.0/jasmine.js"></script>
7
+ <script type="text/javascript" src="lib/jasmine-1.1.0/jasmine-html.js"></script>
8
+ <% if @project.uses_jquery? -%>
9
+ <script type="text/javascript" src="lib/jquery-jasmine.js"></script>
10
+ <% end -%>
9
11
  <!-- include source files here... -->
10
12
  <% if @project.jammit -%>
11
13
  <script src="../public/assets/app.js"></script>
@@ -1,3 +1,489 @@
1
+ jasmine.HtmlReporterHelpers = {};
2
+
3
+ jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
4
+ var el = document.createElement(type);
5
+
6
+ for (var i = 2; i < arguments.length; i++) {
7
+ var child = arguments[i];
8
+
9
+ if (typeof child === 'string') {
10
+ el.appendChild(document.createTextNode(child));
11
+ } else {
12
+ if (child) {
13
+ el.appendChild(child);
14
+ }
15
+ }
16
+ }
17
+
18
+ for (var attr in attrs) {
19
+ if (attr == "className") {
20
+ el[attr] = attrs[attr];
21
+ } else {
22
+ el.setAttribute(attr, attrs[attr]);
23
+ }
24
+ }
25
+
26
+ return el;
27
+ };
28
+
29
+ jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
30
+ var results = child.results();
31
+ var status = results.passed() ? 'passed' : 'failed';
32
+ if (results.skipped) {
33
+ status = 'skipped';
34
+ }
35
+
36
+ return status;
37
+ };
38
+
39
+ jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
40
+ var parentDiv = this.dom.summary;
41
+ var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
42
+ var parent = child[parentSuite];
43
+
44
+ if (parent) {
45
+ if (typeof this.views.suites[parent.id] == 'undefined') {
46
+ this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
47
+ }
48
+ parentDiv = this.views.suites[parent.id].element;
49
+ }
50
+
51
+ parentDiv.appendChild(childElement);
52
+ };
53
+
54
+
55
+ jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
56
+ for(var fn in jasmine.HtmlReporterHelpers) {
57
+ ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
58
+ }
59
+ };
60
+
61
+ jasmine.HtmlReporter = function(_doc) {
62
+ var self = this;
63
+ var doc = _doc || window.document;
64
+
65
+ var reporterView;
66
+
67
+ var dom = {};
68
+
69
+ // Jasmine Reporter Public Interface
70
+ self.logRunningSpecs = false;
71
+
72
+ self.reportRunnerStarting = function(runner) {
73
+ var specs = runner.specs() || [];
74
+
75
+ if (specs.length == 0) {
76
+ return;
77
+ }
78
+
79
+ createReporterDom(runner.env.versionString());
80
+ doc.body.appendChild(dom.reporter);
81
+
82
+ reporterView = new jasmine.HtmlReporter.ReporterView(dom);
83
+ reporterView.addSpecs(specs, self.specFilter);
84
+ };
85
+
86
+ self.reportRunnerResults = function(runner) {
87
+ reporterView && reporterView.complete();
88
+ };
89
+
90
+ self.reportSuiteResults = function(suite) {
91
+ reporterView.suiteComplete(suite);
92
+ };
93
+
94
+ self.reportSpecStarting = function(spec) {
95
+ if (self.logRunningSpecs) {
96
+ self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
97
+ }
98
+ };
99
+
100
+ self.reportSpecResults = function(spec) {
101
+ reporterView.specComplete(spec);
102
+ };
103
+
104
+ self.log = function() {
105
+ var console = jasmine.getGlobal().console;
106
+ if (console && console.log) {
107
+ if (console.log.apply) {
108
+ console.log.apply(console, arguments);
109
+ } else {
110
+ console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
111
+ }
112
+ }
113
+ };
114
+
115
+ self.specFilter = function(spec) {
116
+ if (!focusedSpecName()) {
117
+ return true;
118
+ }
119
+
120
+ return spec.getFullName().indexOf(focusedSpecName()) === 0;
121
+ };
122
+
123
+ return self;
124
+
125
+ function focusedSpecName() {
126
+ var specName;
127
+
128
+ (function memoizeFocusedSpec() {
129
+ if (specName) {
130
+ return;
131
+ }
132
+
133
+ var paramMap = [];
134
+ var params = doc.location.search.substring(1).split('&');
135
+
136
+ for (var i = 0; i < params.length; i++) {
137
+ var p = params[i].split('=');
138
+ paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
139
+ }
140
+
141
+ specName = paramMap.spec;
142
+ })();
143
+
144
+ return specName;
145
+ }
146
+
147
+ function createReporterDom(version) {
148
+ dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
149
+ dom.banner = self.createDom('div', { className: 'banner' },
150
+ self.createDom('span', { className: 'title' }, "Jasmine "),
151
+ self.createDom('span', { className: 'version' }, version)),
152
+
153
+ dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
154
+ dom.alert = self.createDom('div', {className: 'alert'}),
155
+ dom.results = self.createDom('div', {className: 'results'},
156
+ dom.summary = self.createDom('div', { className: 'summary' }),
157
+ dom.details = self.createDom('div', { id: 'details' }))
158
+ );
159
+ }
160
+ };
161
+ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);jasmine.HtmlReporterHelpers = {};
162
+
163
+ jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
164
+ var el = document.createElement(type);
165
+
166
+ for (var i = 2; i < arguments.length; i++) {
167
+ var child = arguments[i];
168
+
169
+ if (typeof child === 'string') {
170
+ el.appendChild(document.createTextNode(child));
171
+ } else {
172
+ if (child) {
173
+ el.appendChild(child);
174
+ }
175
+ }
176
+ }
177
+
178
+ for (var attr in attrs) {
179
+ if (attr == "className") {
180
+ el[attr] = attrs[attr];
181
+ } else {
182
+ el.setAttribute(attr, attrs[attr]);
183
+ }
184
+ }
185
+
186
+ return el;
187
+ };
188
+
189
+ jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
190
+ var results = child.results();
191
+ var status = results.passed() ? 'passed' : 'failed';
192
+ if (results.skipped) {
193
+ status = 'skipped';
194
+ }
195
+
196
+ return status;
197
+ };
198
+
199
+ jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
200
+ var parentDiv = this.dom.summary;
201
+ var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
202
+ var parent = child[parentSuite];
203
+
204
+ if (parent) {
205
+ if (typeof this.views.suites[parent.id] == 'undefined') {
206
+ this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
207
+ }
208
+ parentDiv = this.views.suites[parent.id].element;
209
+ }
210
+
211
+ parentDiv.appendChild(childElement);
212
+ };
213
+
214
+
215
+ jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
216
+ for(var fn in jasmine.HtmlReporterHelpers) {
217
+ ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
218
+ }
219
+ };
220
+
221
+ jasmine.HtmlReporter.ReporterView = function(dom) {
222
+ this.startedAt = new Date();
223
+ this.runningSpecCount = 0;
224
+ this.completeSpecCount = 0;
225
+ this.passedCount = 0;
226
+ this.failedCount = 0;
227
+ this.skippedCount = 0;
228
+
229
+ this.createResultsMenu = function() {
230
+ this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
231
+ this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
232
+ ' | ',
233
+ this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
234
+
235
+ this.summaryMenuItem.onclick = function() {
236
+ dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
237
+ };
238
+
239
+ this.detailsMenuItem.onclick = function() {
240
+ showDetails();
241
+ };
242
+ };
243
+
244
+ this.addSpecs = function(specs, specFilter) {
245
+ this.totalSpecCount = specs.length;
246
+
247
+ this.views = {
248
+ specs: {},
249
+ suites: {}
250
+ };
251
+
252
+ for (var i = 0; i < specs.length; i++) {
253
+ var spec = specs[i];
254
+ this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
255
+ if (specFilter(spec)) {
256
+ this.runningSpecCount++;
257
+ }
258
+ }
259
+ };
260
+
261
+ this.specComplete = function(spec) {
262
+ this.completeSpecCount++;
263
+
264
+ if (isUndefined(this.views.specs[spec.id])) {
265
+ this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
266
+ }
267
+
268
+ var specView = this.views.specs[spec.id];
269
+
270
+ switch (specView.status()) {
271
+ case 'passed':
272
+ this.passedCount++;
273
+ break;
274
+
275
+ case 'failed':
276
+ this.failedCount++;
277
+ break;
278
+
279
+ case 'skipped':
280
+ this.skippedCount++;
281
+ break;
282
+ }
283
+
284
+ specView.refresh();
285
+ this.refresh();
286
+ };
287
+
288
+ this.suiteComplete = function(suite) {
289
+ var suiteView = this.views.suites[suite.id];
290
+ if (isUndefined(suiteView)) {
291
+ return;
292
+ }
293
+ suiteView.refresh();
294
+ };
295
+
296
+ this.refresh = function() {
297
+
298
+ if (isUndefined(this.resultsMenu)) {
299
+ this.createResultsMenu();
300
+ }
301
+
302
+ // currently running UI
303
+ if (isUndefined(this.runningAlert)) {
304
+ this.runningAlert = this.createDom('a', {href: "?", className: "runningAlert bar"});
305
+ dom.alert.appendChild(this.runningAlert);
306
+ }
307
+ this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
308
+
309
+ // skipped specs UI
310
+ if (isUndefined(this.skippedAlert)) {
311
+ this.skippedAlert = this.createDom('a', {href: "?", className: "skippedAlert bar"});
312
+ }
313
+
314
+ this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
315
+
316
+ if (this.skippedCount === 1 && isDefined(dom.alert)) {
317
+ dom.alert.appendChild(this.skippedAlert);
318
+ }
319
+
320
+ // passing specs UI
321
+ if (isUndefined(this.passedAlert)) {
322
+ this.passedAlert = this.createDom('span', {href: "?", className: "passingAlert bar"});
323
+ }
324
+ this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
325
+
326
+ // failing specs UI
327
+ if (isUndefined(this.failedAlert)) {
328
+ this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
329
+ }
330
+ this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
331
+
332
+ if (this.failedCount === 1 && isDefined(dom.alert)) {
333
+ dom.alert.appendChild(this.failedAlert);
334
+ dom.alert.appendChild(this.resultsMenu);
335
+ }
336
+
337
+ // summary info
338
+ this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
339
+ this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
340
+ };
341
+
342
+ this.complete = function() {
343
+ dom.alert.removeChild(this.runningAlert);
344
+
345
+ this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
346
+
347
+ if (this.failedCount === 0) {
348
+ dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
349
+ } else {
350
+ showDetails();
351
+ }
352
+
353
+ dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
354
+ };
355
+
356
+ return this;
357
+
358
+ function showDetails() {
359
+ if (dom.reporter.className.search(/showDetails/) === -1) {
360
+ dom.reporter.className += " showDetails";
361
+ }
362
+ }
363
+
364
+ function isUndefined(obj) {
365
+ return typeof obj === 'undefined';
366
+ }
367
+
368
+ function isDefined(obj) {
369
+ return !isUndefined(obj);
370
+ }
371
+
372
+ function specPluralizedFor(count) {
373
+ var str = count + " spec";
374
+ if (count > 1) {
375
+ str += "s"
376
+ }
377
+ return str;
378
+ }
379
+
380
+ };
381
+
382
+ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
383
+
384
+
385
+ jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
386
+ this.spec = spec;
387
+ this.dom = dom;
388
+ this.views = views;
389
+
390
+ this.symbol = this.createDom('li', { className: 'pending' });
391
+ this.dom.symbolSummary.appendChild(this.symbol);
392
+
393
+ this.summary = this.createDom('div', { className: 'specSummary' },
394
+ this.createDom('a', {
395
+ className: 'description',
396
+ href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
397
+ title: this.spec.getFullName()
398
+ }, this.spec.description)
399
+ );
400
+
401
+ this.detail = this.createDom('div', { className: 'specDetail' },
402
+ this.createDom('a', {
403
+ className: 'description',
404
+ href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
405
+ title: this.spec.getFullName()
406
+ }, this.spec.getFullName())
407
+ );
408
+ };
409
+
410
+ jasmine.HtmlReporter.SpecView.prototype.status = function() {
411
+ return this.getSpecStatus(this.spec);
412
+ };
413
+
414
+ jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
415
+ this.symbol.className = this.status();
416
+
417
+ switch (this.status()) {
418
+ case 'skipped':
419
+ break;
420
+
421
+ case 'passed':
422
+ this.appendSummaryToSuiteDiv();
423
+ break;
424
+
425
+ case 'failed':
426
+ this.appendSummaryToSuiteDiv();
427
+ this.appendFailureDetail();
428
+ break;
429
+ }
430
+ };
431
+
432
+ jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
433
+ this.summary.className += ' ' + this.status();
434
+ this.appendToSummary(this.spec, this.summary);
435
+ };
436
+
437
+ jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
438
+ this.detail.className += ' ' + this.status();
439
+
440
+ var resultItems = this.spec.results().getItems();
441
+ var messagesDiv = this.createDom('div', { className: 'messages' });
442
+
443
+ for (var i = 0; i < resultItems.length; i++) {
444
+ var result = resultItems[i];
445
+
446
+ if (result.type == 'log') {
447
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
448
+ } else if (result.type == 'expect' && result.passed && !result.passed()) {
449
+ messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
450
+
451
+ if (result.trace.stack) {
452
+ messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
453
+ }
454
+ }
455
+ }
456
+
457
+ if (messagesDiv.childNodes.length > 0) {
458
+ this.detail.appendChild(messagesDiv);
459
+ this.dom.details.appendChild(this.detail);
460
+ }
461
+ };
462
+
463
+ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
464
+ this.suite = suite;
465
+ this.dom = dom;
466
+ this.views = views;
467
+
468
+ this.element = this.createDom('div', { className: 'suite' },
469
+ this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(this.suite.getFullName()) }, this.suite.description)
470
+ );
471
+
472
+ this.appendToSummary(this.suite, this.element);
473
+ };
474
+
475
+ jasmine.HtmlReporter.SuiteView.prototype.status = function() {
476
+ return this.getSpecStatus(this.suite);
477
+ };
478
+
479
+ jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
480
+ this.element.className += " " + this.status();
481
+ };
482
+
483
+ jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
484
+
485
+ /* @deprecated Use jasmine.HtmlReporter instead
486
+ */
1
487
  jasmine.TrivialReporter = function(doc) {
2
488
  this.document = doc || document;
3
489
  this.suiteDivs = {};
@@ -31,7 +517,7 @@ jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarA
31
517
  jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
32
518
  var showPassed, showSkipped;
33
519
 
34
- this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
520
+ this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
35
521
  this.createDom('div', { className: 'banner' },
36
522
  this.createDom('div', { className: 'logo' },
37
523
  this.createDom('span', { className: 'title' }, "Jasmine"),
@@ -1,166 +1,81 @@
1
- body {
2
- font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
3
- }
4
-
5
-
6
- .jasmine_reporter a:visited, .jasmine_reporter a {
7
- color: #303;
8
- }
9
-
10
- .jasmine_reporter a:hover, .jasmine_reporter a:active {
11
- color: blue;
12
- }
13
-
14
- .run_spec {
15
- float:right;
16
- padding-right: 5px;
17
- font-size: .8em;
18
- text-decoration: none;
19
- }
20
-
21
- .jasmine_reporter {
22
- margin: 0 5px;
23
- }
24
-
25
- .banner {
26
- color: #303;
27
- background-color: #fef;
28
- padding: 5px;
29
- }
30
-
31
- .logo {
32
- float: left;
33
- font-size: 1.1em;
34
- padding-left: 5px;
35
- }
36
-
37
- .logo .version {
38
- font-size: .6em;
39
- padding-left: 1em;
40
- }
41
-
42
- .runner.running {
43
- background-color: yellow;
44
- }
45
-
46
-
47
- .options {
48
- text-align: right;
49
- font-size: .8em;
50
- }
51
-
52
-
53
-
54
-
55
- .suite {
56
- border: 1px outset gray;
57
- margin: 5px 0;
58
- padding-left: 1em;
59
- }
60
-
61
- .suite .suite {
62
- margin: 5px;
63
- }
64
-
65
- .suite.passed {
66
- background-color: #dfd;
67
- }
68
-
69
- .suite.failed {
70
- background-color: #fdd;
71
- }
72
-
73
- .spec {
74
- margin: 5px;
75
- padding-left: 1em;
76
- clear: both;
77
- }
78
-
79
- .spec.failed, .spec.passed, .spec.skipped {
80
- padding-bottom: 5px;
81
- border: 1px solid gray;
82
- }
83
-
84
- .spec.failed {
85
- background-color: #fbb;
86
- border-color: red;
87
- }
88
-
89
- .spec.passed {
90
- background-color: #bfb;
91
- border-color: green;
92
- }
93
-
94
- .spec.skipped {
95
- background-color: #bbb;
96
- }
97
-
98
- .messages {
99
- border-left: 1px dashed gray;
100
- padding-left: 1em;
101
- padding-right: 1em;
102
- }
103
-
104
- .passed {
105
- background-color: #cfc;
106
- display: none;
107
- }
108
-
109
- .failed {
110
- background-color: #fbb;
111
- }
112
-
113
- .skipped {
114
- color: #777;
115
- background-color: #eee;
116
- display: none;
117
- }
118
-
119
-
120
- /*.resultMessage {*/
121
- /*white-space: pre;*/
122
- /*}*/
123
-
124
- .resultMessage span.result {
125
- display: block;
126
- line-height: 2em;
127
- color: black;
128
- }
129
-
130
- .resultMessage .mismatch {
131
- color: black;
132
- }
133
-
134
- .stackTrace {
135
- white-space: pre;
136
- font-size: .8em;
137
- margin-left: 10px;
138
- max-height: 5em;
139
- overflow: auto;
140
- border: 1px inset red;
141
- padding: 1em;
142
- background: #eef;
143
- }
144
-
145
- .finished-at {
146
- padding-left: 1em;
147
- font-size: .6em;
148
- }
149
-
150
- .show-passed .passed,
151
- .show-skipped .skipped {
152
- display: block;
153
- }
154
-
155
-
156
- #jasmine_content {
157
- position:fixed;
158
- right: 100%;
159
- }
160
-
161
- .runner {
162
- border: 1px solid gray;
163
- display: block;
164
- margin: 5px 0;
165
- padding: 2px 0 2px 10px;
166
- }
1
+ body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
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 .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
23
+ #HTMLReporter .runningAlert { background-color: #666666; }
24
+ #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
25
+ #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
26
+ #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
27
+ #HTMLReporter .passingAlert { background-color: #a6b779; }
28
+ #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
29
+ #HTMLReporter .failingAlert { background-color: #cf867e; }
30
+ #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
31
+ #HTMLReporter .results { margin-top: 14px; }
32
+ #HTMLReporter #details { display: none; }
33
+ #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
34
+ #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
35
+ #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
36
+ #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
37
+ #HTMLReporter.showDetails .summary { display: none; }
38
+ #HTMLReporter.showDetails #details { display: block; }
39
+ #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
40
+ #HTMLReporter .summary { margin-top: 14px; }
41
+ #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
42
+ #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
43
+ #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
44
+ #HTMLReporter .description + .suite { margin-top: 0; }
45
+ #HTMLReporter .suite { margin-top: 14px; }
46
+ #HTMLReporter .suite a { color: #333333; }
47
+ #HTMLReporter #details .specDetail { margin-bottom: 28px; }
48
+ #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
49
+ #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
50
+ #HTMLReporter .resultMessage span.result { display: block; }
51
+ #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; }
52
+
53
+ #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;*/ /*}*/ }
54
+ #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
55
+ #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
56
+ #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
57
+ #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
58
+ #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
59
+ #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
60
+ #TrivialReporter .runner.running { background-color: yellow; }
61
+ #TrivialReporter .options { text-align: right; font-size: .8em; }
62
+ #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
63
+ #TrivialReporter .suite .suite { margin: 5px; }
64
+ #TrivialReporter .suite.passed { background-color: #dfd; }
65
+ #TrivialReporter .suite.failed { background-color: #fdd; }
66
+ #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
67
+ #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
68
+ #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
69
+ #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
70
+ #TrivialReporter .spec.skipped { background-color: #bbb; }
71
+ #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
72
+ #TrivialReporter .passed { background-color: #cfc; display: none; }
73
+ #TrivialReporter .failed { background-color: #fbb; }
74
+ #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
75
+ #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
76
+ #TrivialReporter .resultMessage .mismatch { color: black; }
77
+ #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
78
+ #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
79
+ #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
80
+ #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
81
+ #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
@@ -196,6 +196,21 @@ jasmine.any = function(clazz) {
196
196
  return new jasmine.Matchers.Any(clazz);
197
197
  };
198
198
 
199
+ /**
200
+ * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
201
+ * attributes on the object.
202
+ *
203
+ * @example
204
+ * // don't care about any other attributes than foo.
205
+ * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
206
+ *
207
+ * @param sample {Object} sample
208
+ * @returns matchable object for the sample
209
+ */
210
+ jasmine.objectContaining = function (sample) {
211
+ return new jasmine.Matchers.ObjectContaining(sample);
212
+ };
213
+
199
214
  /**
200
215
  * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
201
216
  *
@@ -914,11 +929,19 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
914
929
  return a.getTime() == b.getTime();
915
930
  }
916
931
 
917
- if (a instanceof jasmine.Matchers.Any) {
932
+ if (a.jasmineMatches) {
933
+ return a.jasmineMatches(b);
934
+ }
935
+
936
+ if (b.jasmineMatches) {
937
+ return b.jasmineMatches(a);
938
+ }
939
+
940
+ if (a instanceof jasmine.Matchers.ObjectContaining) {
918
941
  return a.matches(b);
919
942
  }
920
943
 
921
- if (b instanceof jasmine.Matchers.Any) {
944
+ if (b instanceof jasmine.Matchers.ObjectContaining) {
922
945
  return b.matches(a);
923
946
  }
924
947
 
@@ -1212,7 +1235,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
1212
1235
  /**
1213
1236
  * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
1214
1237
  * @param expected
1215
- * @deprecated as of 1.0. Use not.toNotEqual() instead.
1238
+ * @deprecated as of 1.0. Use not.toEqual() instead.
1216
1239
  */
1217
1240
  jasmine.Matchers.prototype.toNotEqual = function(expected) {
1218
1241
  return !this.env.equals_(this.actual, expected);
@@ -1385,7 +1408,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
1385
1408
  * Matcher that checks that the expected item is NOT an element in the actual Array.
1386
1409
  *
1387
1410
  * @param {Object} expected
1388
- * @deprecated as of 1.0. Use not.toNotContain() instead.
1411
+ * @deprecated as of 1.0. Use not.toContain() instead.
1389
1412
  */
1390
1413
  jasmine.Matchers.prototype.toNotContain = function(expected) {
1391
1414
  return !this.env.contains_(this.actual, expected);
@@ -1453,7 +1476,7 @@ jasmine.Matchers.Any = function(expectedClass) {
1453
1476
  this.expectedClass = expectedClass;
1454
1477
  };
1455
1478
 
1456
- jasmine.Matchers.Any.prototype.matches = function(other) {
1479
+ jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
1457
1480
  if (this.expectedClass == String) {
1458
1481
  return typeof other == 'string' || other instanceof String;
1459
1482
  }
@@ -1473,10 +1496,39 @@ jasmine.Matchers.Any.prototype.matches = function(other) {
1473
1496
  return other instanceof this.expectedClass;
1474
1497
  };
1475
1498
 
1476
- jasmine.Matchers.Any.prototype.toString = function() {
1499
+ jasmine.Matchers.Any.prototype.jasmineToString = function() {
1477
1500
  return '<jasmine.any(' + this.expectedClass + ')>';
1478
1501
  };
1479
1502
 
1503
+ jasmine.Matchers.ObjectContaining = function (sample) {
1504
+ this.sample = sample;
1505
+ };
1506
+
1507
+ jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
1508
+ mismatchKeys = mismatchKeys || [];
1509
+ mismatchValues = mismatchValues || [];
1510
+
1511
+ var env = jasmine.getEnv();
1512
+
1513
+ var hasKey = function(obj, keyName) {
1514
+ return obj != null && obj[keyName] !== jasmine.undefined;
1515
+ };
1516
+
1517
+ for (var property in this.sample) {
1518
+ if (!hasKey(other, property) && hasKey(this.sample, property)) {
1519
+ mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
1520
+ }
1521
+ else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
1522
+ 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.");
1523
+ }
1524
+ }
1525
+
1526
+ return (mismatchKeys.length === 0 && mismatchValues.length === 0);
1527
+ };
1528
+
1529
+ jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
1530
+ return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
1531
+ };
1480
1532
  /**
1481
1533
  * @constructor
1482
1534
  */
@@ -1617,8 +1669,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
1617
1669
  this.emitScalar('null');
1618
1670
  } else if (value === jasmine.getGlobal()) {
1619
1671
  this.emitScalar('<global>');
1620
- } else if (value instanceof jasmine.Matchers.Any) {
1621
- this.emitScalar(value.toString());
1672
+ } else if (value.jasmineToString) {
1673
+ this.emitScalar(value.jasmineToString());
1622
1674
  } else if (typeof value === 'string') {
1623
1675
  this.emitString(value);
1624
1676
  } else if (jasmine.isSpy(value)) {
@@ -2472,5 +2524,5 @@ jasmine.version_= {
2472
2524
  "major": 1,
2473
2525
  "minor": 1,
2474
2526
  "build": 0,
2475
- "revision": 1315677058
2527
+ "revision": 1330200206
2476
2528
  };
@@ -0,0 +1,306 @@
1
+ var readFixtures = function() {
2
+ return jasmine.getFixtures().proxyCallTo_('read', arguments);
3
+ };
4
+
5
+ var preloadFixtures = function() {
6
+ jasmine.getFixtures().proxyCallTo_('preload', arguments);
7
+ };
8
+
9
+ var loadFixtures = function() {
10
+ jasmine.getFixtures().proxyCallTo_('load', arguments);
11
+ };
12
+
13
+ var setFixtures = function(html) {
14
+ jasmine.getFixtures().set(html);
15
+ };
16
+
17
+ var sandbox = function(attributes) {
18
+ return jasmine.getFixtures().sandbox(attributes);
19
+ };
20
+
21
+ var spyOnEvent = function(selector, eventName) {
22
+ jasmine.JQuery.events.spyOn(selector, eventName);
23
+ };
24
+
25
+ jasmine.getFixtures = function() {
26
+ return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures();
27
+ };
28
+
29
+ jasmine.Fixtures = function() {
30
+ this.containerId = 'jasmine-fixtures';
31
+ this.fixturesCache_ = {};
32
+ this.fixturesPath = 'spec/javascripts/fixtures';
33
+ };
34
+
35
+ jasmine.Fixtures.prototype.set = function(html) {
36
+ this.cleanUp();
37
+ this.createContainer_(html);
38
+ };
39
+
40
+ jasmine.Fixtures.prototype.preload = function() {
41
+ this.read.apply(this, arguments);
42
+ };
43
+
44
+ jasmine.Fixtures.prototype.load = function() {
45
+ this.cleanUp();
46
+ this.createContainer_(this.read.apply(this, arguments));
47
+ };
48
+
49
+ jasmine.Fixtures.prototype.read = function() {
50
+ var htmlChunks = [];
51
+
52
+ var fixtureUrls = arguments;
53
+ for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) {
54
+ htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex]));
55
+ }
56
+
57
+ return htmlChunks.join('');
58
+ };
59
+
60
+ jasmine.Fixtures.prototype.clearCache = function() {
61
+ this.fixturesCache_ = {};
62
+ };
63
+
64
+ jasmine.Fixtures.prototype.cleanUp = function() {
65
+ jQuery('#' + this.containerId).remove();
66
+ };
67
+
68
+ jasmine.Fixtures.prototype.sandbox = function(attributes) {
69
+ var attributesToSet = attributes || {};
70
+ return jQuery('<div id="sandbox" />').attr(attributesToSet);
71
+ };
72
+
73
+ jasmine.Fixtures.prototype.createContainer_ = function(html) {
74
+ var container;
75
+ if(html instanceof jQuery) {
76
+ container = jQuery('<div id="' + this.containerId + '" />');
77
+ container.html(html);
78
+ } else {
79
+ container = '<div id="' + this.containerId + '">' + html + '</div>'
80
+ }
81
+ jQuery('body').append(container);
82
+ };
83
+
84
+ jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) {
85
+ if (typeof this.fixturesCache_[url] == 'undefined') {
86
+ this.loadFixtureIntoCache_(url);
87
+ }
88
+ return this.fixturesCache_[url];
89
+ };
90
+
91
+ jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(relativeUrl) {
92
+ var url = this.fixturesPath.match('/$') ? this.fixturesPath + relativeUrl : this.fixturesPath + '/' + relativeUrl;
93
+ var request = new XMLHttpRequest();
94
+ request.open("GET", url + "?" + new Date().getTime(), false);
95
+ request.send(null);
96
+ this.fixturesCache_[relativeUrl] = request.responseText;
97
+ };
98
+
99
+ jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) {
100
+ return this[methodName].apply(this, passedArguments);
101
+ };
102
+
103
+
104
+ jasmine.JQuery = function() {};
105
+
106
+ jasmine.JQuery.browserTagCaseIndependentHtml = function(html) {
107
+ return jQuery('<div/>').append(html).html();
108
+ };
109
+
110
+ jasmine.JQuery.elementToString = function(element) {
111
+ return jQuery('<div />').append($(element).clone()).html();
112
+ };
113
+
114
+ jasmine.JQuery.matchersClass = {};
115
+
116
+ (function(namespace) {
117
+ var data = {
118
+ spiedEvents: {},
119
+ handlers: []
120
+ };
121
+
122
+ namespace.events = {
123
+ spyOn: function(selector, eventName) {
124
+ var handler = function(e) {
125
+ data.spiedEvents[[selector, eventName]] = e;
126
+ };
127
+ jQuery(selector).bind(eventName, handler);
128
+ data.handlers.push(handler);
129
+ },
130
+
131
+ wasTriggered: function(selector, eventName) {
132
+ return !!(data.spiedEvents[[selector, eventName]]);
133
+ },
134
+
135
+ wasPrevented: function(selector, eventName) {
136
+ return data.spiedEvents[[selector, eventName]].isDefaultPrevented();
137
+ },
138
+
139
+ cleanUp: function() {
140
+ data.spiedEvents = {};
141
+ data.handlers = [];
142
+ }
143
+ }
144
+ })(jasmine.JQuery);
145
+
146
+ (function(){
147
+ var jQueryMatchers = {
148
+ toHaveClass: function(className) {
149
+ return this.actual.hasClass(className);
150
+ },
151
+
152
+ toBeVisible: function() {
153
+ return this.actual.is(':visible');
154
+ },
155
+
156
+ toBeHidden: function() {
157
+ return this.actual.is(':hidden');
158
+ },
159
+
160
+ toBeSelected: function() {
161
+ return this.actual.is(':selected');
162
+ },
163
+
164
+ toBeChecked: function() {
165
+ return this.actual.is(':checked');
166
+ },
167
+
168
+ toBeEmpty: function() {
169
+ return this.actual.is(':empty');
170
+ },
171
+
172
+ toExist: function() {
173
+ return this.actual.size() > 0;
174
+ },
175
+
176
+ toHaveAttr: function(attributeName, expectedAttributeValue) {
177
+ return hasProperty(this.actual.attr(attributeName), expectedAttributeValue);
178
+ },
179
+
180
+ toHaveProp: function(propertyName, expectedPropertyValue) {
181
+ return hasProperty(this.actual.prop(propertyName), expectedPropertyValue);
182
+ },
183
+
184
+ toHaveId: function(id) {
185
+ return this.actual.attr('id') == id;
186
+ },
187
+
188
+ toHaveHtml: function(html) {
189
+ return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html);
190
+ },
191
+
192
+ toHaveText: function(text) {
193
+ var trimmedText = $.trim(this.actual.text());
194
+ if (text && jQuery.isFunction(text.test)) {
195
+ return text.test(trimmedText);
196
+ } else {
197
+ return trimmedText == text;
198
+ }
199
+ },
200
+
201
+ toHaveValue: function(value) {
202
+ return this.actual.val() == value;
203
+ },
204
+
205
+ toHaveData: function(key, expectedValue) {
206
+ return hasProperty(this.actual.data(key), expectedValue);
207
+ },
208
+
209
+ toBe: function(selector) {
210
+ return this.actual.is(selector);
211
+ },
212
+
213
+ toContain: function(selector) {
214
+ return this.actual.find(selector).size() > 0;
215
+ },
216
+
217
+ toBeDisabled: function(selector){
218
+ return this.actual.is(':disabled');
219
+ },
220
+
221
+ toBeFocused: function(selector) {
222
+ return this.actual.is(':focus');
223
+ },
224
+
225
+ // tests the existence of a specific event binding
226
+ toHandle: function(eventName) {
227
+ var events = this.actual.data("events");
228
+ return events && events[eventName].length > 0;
229
+ },
230
+
231
+ // tests the existence of a specific event binding + handler
232
+ toHandleWith: function(eventName, eventHandler) {
233
+ var stack = this.actual.data("events")[eventName];
234
+ var i;
235
+ for (i = 0; i < stack.length; i++) {
236
+ if (stack[i].handler == eventHandler) {
237
+ return true;
238
+ }
239
+ }
240
+ return false;
241
+ }
242
+ };
243
+
244
+ var hasProperty = function(actualValue, expectedValue) {
245
+ if (expectedValue === undefined) {
246
+ return actualValue !== undefined;
247
+ }
248
+ return actualValue == expectedValue;
249
+ };
250
+
251
+ var bindMatcher = function(methodName) {
252
+ var builtInMatcher = jasmine.Matchers.prototype[methodName];
253
+
254
+ jasmine.JQuery.matchersClass[methodName] = function() {
255
+ if (this.actual
256
+ && (this.actual instanceof jQuery
257
+ || jasmine.isDomNode(this.actual))) {
258
+ this.actual = $(this.actual);
259
+ var result = jQueryMatchers[methodName].apply(this, arguments);
260
+ this.actual = jasmine.JQuery.elementToString(this.actual);
261
+ return result;
262
+ }
263
+
264
+ if (builtInMatcher) {
265
+ return builtInMatcher.apply(this, arguments);
266
+ }
267
+
268
+ return false;
269
+ };
270
+ };
271
+
272
+ for(var methodName in jQueryMatchers) {
273
+ bindMatcher(methodName);
274
+ }
275
+ })();
276
+
277
+ beforeEach(function() {
278
+ this.addMatchers(jasmine.JQuery.matchersClass);
279
+ this.addMatchers({
280
+ toHaveBeenTriggeredOn: function(selector) {
281
+ this.message = function() {
282
+ return [
283
+ "Expected event " + this.actual + " to have been triggered on " + selector,
284
+ "Expected event " + this.actual + " not to have been triggered on " + selector
285
+ ];
286
+ };
287
+ return jasmine.JQuery.events.wasTriggered($(selector), this.actual);
288
+ }
289
+ });
290
+ this.addMatchers({
291
+ toHaveBeenPreventedOn: function(selector) {
292
+ this.message = function() {
293
+ return [
294
+ "Expected event " + this.actual + " to have been prevented on " + selector,
295
+ "Expected event " + this.actual + " not to have been prevented on " + selector
296
+ ];
297
+ };
298
+ return jasmine.JQuery.events.wasPrevented(selector, this.actual);
299
+ }
300
+ });
301
+ });
302
+
303
+ afterEach(function() {
304
+ jasmine.getFixtures().cleanUp();
305
+ jasmine.JQuery.events.cleanUp();
306
+ });
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qedproject
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 3
9
- - 0
10
- version: 0.3.0
9
+ - 1
10
+ version: 0.3.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Brian P. Hogan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2012-04-19 00:00:00 -05:00
18
+ date: 2012-04-26 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -230,6 +230,8 @@ files:
230
230
  - vendor/skeleton/layout.css
231
231
  - vendor/skeleton/favicon.ico
232
232
  - vendor/skeleton/skeleton.css
233
+ - vendor/jasmine-jquery/jasmine-jquery.js
234
+ - vendor/jasmine/lib/jasmine-1.1.0/jasmine_favicon.png
233
235
  - vendor/jasmine/lib/jasmine-1.1.0/jasmine-html.js
234
236
  - vendor/jasmine/lib/jasmine-1.1.0/jasmine.css
235
237
  - vendor/jasmine/lib/jasmine-1.1.0/jasmine.js