qedproject 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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