|
1 | 1 | (function () { |
| 2 | + 'use strict'; |
2 | 3 | /* jshint undef: true, unused: true */ |
3 | 4 | /* globals QUnit, test, Rx, equal */ |
| 5 | + var Observable = Rx.Observable, |
| 6 | + slice = Array.prototype.slice, |
| 7 | + onNext = Rx.ReactiveTest.onNext, |
| 8 | + onError = Rx.ReactiveTest.onError; |
4 | 9 |
|
5 | | - QUnit.module('FromEventPattern'); |
| 10 | + QUnit.module('fromEventPattern', { |
| 11 | + setup : function() { |
| 12 | + this.scheduler = new Rx.TestScheduler(); |
| 13 | + } |
| 14 | + }); |
| 15 | + |
| 16 | + function FakeDojoElement(nodeName) { |
| 17 | + this.listeners = {}; |
| 18 | + this.nodeName = nodeName; |
| 19 | + this.onCalled = false; |
| 20 | + this.offCalled = false; |
| 21 | + } |
| 22 | + |
| 23 | + FakeDojoElement.prototype.on = function (eventName, handler) { |
| 24 | + this.listeners[eventName] = handler; |
| 25 | + this.onCalled = true; |
| 26 | + return new FakeDojoDisposable(this, eventName); |
| 27 | + }; |
| 28 | + |
| 29 | + FakeDojoElement.prototype.trigger = function (eventName) { |
| 30 | + var args = slice.call(arguments, 1); |
| 31 | + if (eventName in this.listeners) { |
| 32 | + this.listeners[eventName].apply(null, args); |
| 33 | + } |
| 34 | + }; |
| 35 | + |
| 36 | + function FakeDojoDisposable(parent, eventName) { |
| 37 | + this.parent = parent; |
| 38 | + this.eventName = eventName; |
| 39 | + } |
| 40 | + |
| 41 | + FakeDojoDisposable.prototype.disconnect = function () { |
| 42 | + delete this.parent.listeners[this.eventName]; |
| 43 | + this.parent.offCalled = true; |
| 44 | + }; |
| 45 | + |
| 46 | + test('fromEventPattern with return from add handler', function () { |
| 47 | + var element = new FakeDojoElement('foo'); |
| 48 | + |
| 49 | + this.scheduler.scheduleFuture(null, 210, function() { |
| 50 | + equal(element.onCalled, true); |
| 51 | + equal(element.offCalled, false); |
| 52 | + }); |
| 53 | + |
| 54 | + this.scheduler.scheduleFuture(null, 220, function() { |
| 55 | + element.trigger('someEvent', 42); |
| 56 | + }); |
| 57 | + |
| 58 | + var result = this.scheduler.startScheduler(function() { |
| 59 | + return Observable.fromEventPattern( |
| 60 | + function (h) { return element.on('someEvent', h); }, |
| 61 | + function (_, d) { d.disconnect(); } |
| 62 | + ); |
| 63 | + }); |
| 64 | + |
| 65 | + result.messages.assertEqual(onNext(220, 42)); |
| 66 | + |
| 67 | + equal(element.offCalled, true); |
| 68 | + }); |
6 | 69 |
|
7 | | - var Observable = Rx.Observable, |
8 | | - slice = Array.prototype.slice; |
9 | 70 |
|
10 | 71 | /** Fake DOM Element */ |
11 | 72 | function FakeDOMStandardElement(nodeName) { |
|
15 | 76 | this.removeEventListenerCalled = false; |
16 | 77 | } |
17 | 78 |
|
18 | | - FakeDOMStandardElement.prototype.addEventListener = function (eventName, handler) { |
| 79 | + FakeDOMStandardElement.prototype.addEventListener = function (eventName, handler, useCapture) { |
19 | 80 | this.listeners[eventName] = handler; |
20 | 81 | this.addEventListenerCalled = true; |
21 | 82 | }; |
22 | 83 |
|
23 | | - FakeDOMStandardElement.prototype.removeEventListener = function (eventName, handler) { |
| 84 | + FakeDOMStandardElement.prototype.removeEventListener = function (eventName, handler, useCapture) { |
24 | 85 | delete this.listeners[eventName]; |
25 | 86 | this.removeEventListenerCalled = true; |
26 | 87 | }; |
|
32 | 93 | } |
33 | 94 | }; |
34 | 95 |
|
35 | | - test('Event 1', function () { |
| 96 | + test('fromEventPattern', function () { |
36 | 97 | var element = new FakeDOMStandardElement('foo'); |
37 | 98 |
|
38 | | - var d = Observable.fromEventPattern( |
39 | | - function (h) { element.addEventListener('someEvent', h, false); }, |
40 | | - function (h) { element.removeEventListener('someEvent', h, false); } |
41 | | - ) |
42 | | - .subscribe(function (x) { |
43 | | - equal(x, 42); |
| 99 | + this.scheduler.scheduleFuture(null, 210, function() { |
| 100 | + equal(element.addEventListenerCalled, true); |
| 101 | + equal(element.removeEventListenerCalled, false); |
44 | 102 | }); |
45 | 103 |
|
46 | | - element.trigger('someEvent', 42); |
47 | | - equal(element.addEventListenerCalled, true); |
48 | | - equal(element.removeEventListenerCalled, false); |
| 104 | + this.scheduler.scheduleFuture(null, 220, function() { |
| 105 | + element.trigger('someEvent', 42); |
| 106 | + }); |
49 | 107 |
|
50 | | - d.dispose(); |
| 108 | + var result = this.scheduler.startScheduler(function() { |
| 109 | + return Observable.fromEventPattern( |
| 110 | + function (h) { element.addEventListener('someEvent', h); }, |
| 111 | + function (h) { element.removeEventListener('someEvent', h); } |
| 112 | + ); |
| 113 | + }); |
| 114 | + |
| 115 | + result.messages.assertEqual(onNext(220, 42)); |
51 | 116 |
|
52 | 117 | equal(element.removeEventListenerCalled, true); |
53 | 118 | }); |
54 | 119 |
|
55 | | - test('Event 2', function () { |
| 120 | + test('fromEventPattern selector', function () { |
56 | 121 | var element = new FakeDOMStandardElement('foo'); |
57 | 122 |
|
58 | | - var d = Observable.fromEventPattern( |
59 | | - function (h) { element.addEventListener('someEvent', h, false); }, |
60 | | - function (h) { element.removeEventListener('someEvent', h, false); }, |
| 123 | + this.scheduler.scheduleFuture(null, 210, function() { |
| 124 | + equal(element.addEventListenerCalled, true); |
| 125 | + equal(element.removeEventListenerCalled, false); |
| 126 | + }); |
| 127 | + |
| 128 | + this.scheduler.scheduleFuture(null, 220, function() { |
| 129 | + element.trigger('someEvent', 'baz', 'quux'); |
| 130 | + }); |
| 131 | + |
| 132 | + var result = this.scheduler.startScheduler(function() { |
| 133 | + return Observable.fromEventPattern( |
| 134 | + function (h) { element.addEventListener('someEvent', h); }, |
| 135 | + function (h) { element.removeEventListener('someEvent', h); }, |
61 | 136 | function (baz, quux) { |
62 | 137 | return { foo: baz, bar: quux }; |
63 | 138 | } |
64 | | - ) |
65 | | - .subscribe(function (x) { |
66 | | - equal(x.foo, 'baz'); |
67 | | - equal(x.bar, 'quux'); |
68 | | - }); |
| 139 | + ); |
| 140 | + }); |
69 | 141 |
|
70 | | - element.trigger('someEvent', 'baz', 'quux'); |
71 | | - equal(element.addEventListenerCalled, true); |
72 | | - equal(element.removeEventListenerCalled, false); |
| 142 | + result.messages.assertEqual( |
| 143 | + onNext(220, {foo: 'baz', bar: 'quux'}) |
| 144 | + ); |
| 145 | + |
| 146 | + equal(element.removeEventListenerCalled, true); |
| 147 | + }); |
| 148 | + |
| 149 | + test('fromEventPattern selector throws', function () { |
| 150 | + var error = new Error(); |
| 151 | + |
| 152 | + var element = new FakeDOMStandardElement('foo'); |
| 153 | + |
| 154 | + this.scheduler.scheduleFuture(null, 210, function() { |
| 155 | + equal(element.addEventListenerCalled, true); |
| 156 | + equal(element.removeEventListenerCalled, false); |
| 157 | + }); |
| 158 | + |
| 159 | + this.scheduler.scheduleFuture(null, 220, function() { |
| 160 | + element.trigger('someEvent', 'baz', 'quux'); |
| 161 | + }); |
| 162 | + |
| 163 | + var result = this.scheduler.startScheduler(function() { |
| 164 | + return Observable.fromEventPattern( |
| 165 | + function (h) { element.addEventListener('someEvent', h); }, |
| 166 | + function (h) { element.removeEventListener('someEvent', h); }, |
| 167 | + function () { |
| 168 | + throw error; |
| 169 | + } |
| 170 | + ); |
| 171 | + }); |
73 | 172 |
|
74 | | - d.dispose(); |
| 173 | + result.messages.assertEqual( |
| 174 | + onError(220, error) |
| 175 | + ); |
75 | 176 |
|
76 | 177 | equal(element.removeEventListenerCalled, true); |
77 | 178 | }); |
|
0 commit comments