unpoly-rails 0.30.0 → 0.30.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.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/lib/assets/javascripts/unpoly/form.js.coffee +22 -41
- data/lib/assets/javascripts/unpoly/util.js.coffee +33 -2
- data/lib/unpoly/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +12 -10
- data/spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee +0 -1
- data/spec_app/spec/javascripts/up/form_spec.js.coffee +146 -70
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +90 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e53ab2c1cbdfe09b80e31d76371d5382ad40f70
|
4
|
+
data.tar.gz: 7ba79eb21d2494bf69b3bc222a4b7e89778671a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5789b11f34c69787dbf6fdd9fe9ed03d6c25c5c76fbf32b7028fcba36a6ecad14072c10d1cf5b4945d7edd104d11e581a302f6ca45b1c15baf4b5aa868c90691
|
7
|
+
data.tar.gz: 3d07d31ce7a01814badad2a7e16fbe4bbf283dc574a6b27818ea9a2ba5a6cff9b9fdcf6a9acfd19b6d505d12f8c84486ea12b7322fae39fa7000cb9af3492c1d
|
data/CHANGELOG.md
CHANGED
@@ -14,6 +14,16 @@ Unreleased
|
|
14
14
|
### Breaking changes
|
15
15
|
|
16
16
|
|
17
|
+
0.30.1
|
18
|
+
------
|
19
|
+
|
20
|
+
### Compatible changes
|
21
|
+
|
22
|
+
- Fix [`up.observe`](/up.observe) not honoring `{ delay }` option
|
23
|
+
- Fix [`[up-observe]`](/up-observe) not honoring `[up-delay]` modifier
|
24
|
+
- Fix many issues with concurrency and slow server responses for [`up.observe`](/up.observe) and [`[up-observe]`](/up-observe)
|
25
|
+
|
26
|
+
|
17
27
|
|
18
28
|
0.30.0
|
19
29
|
------
|
@@ -249,52 +249,35 @@ up.form = (($) ->
|
|
249
249
|
delay = u.option($fields.attr('up-delay'), options.delay, config.observeDelay)
|
250
250
|
delay = parseInt(delay)
|
251
251
|
|
252
|
+
console.debug("Observing with delay %o", delay)
|
253
|
+
|
252
254
|
destructors = u.map $fields, (field) ->
|
253
|
-
observeField($(field),
|
255
|
+
observeField($(field), delay, callback)
|
254
256
|
|
255
257
|
u.sequence(destructors...)
|
256
258
|
|
257
259
|
observeField = ($field, delay, callback) ->
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
if nextCallback
|
270
|
-
returnValue = nextCallback()
|
271
|
-
nextCallback = null
|
272
|
-
returnValue
|
260
|
+
processedValue = u.submittedValue($field)
|
261
|
+
timer = undefined
|
262
|
+
lastCallbackDone = u.resolvedPromise()
|
263
|
+
|
264
|
+
runCallback = (value) ->
|
265
|
+
processedValue = value
|
266
|
+
callbackReturnValue = callback.apply($field.get(0), [value, $field])
|
267
|
+
if u.isPromise(callbackReturnValue)
|
268
|
+
lastCallbackDone = callbackReturnValue
|
269
|
+
else
|
270
|
+
lastCallbackDone = callbackReturnValue
|
273
271
|
|
274
272
|
check = ->
|
275
273
|
value = u.submittedValue($field)
|
276
274
|
# don't run the callback for the check during initialization
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
runAndChain = ->
|
284
|
-
# Only run the callback once the previous callback's
|
285
|
-
# promise resolves.
|
286
|
-
callbackPromise.then ->
|
287
|
-
returnValue = runNextCallback()
|
288
|
-
# If the callback returns a promise, we will remember it
|
289
|
-
# and chain additional callback invocations to it.
|
290
|
-
if u.isPromise(returnValue)
|
291
|
-
callbackPromise = returnValue
|
292
|
-
else
|
293
|
-
callbackPromise = u.resolvedPromise()
|
294
|
-
u.setTimer(delay, runAndChain)
|
295
|
-
|
296
|
-
clearTimer = ->
|
297
|
-
clearTimeout(callbackTimer)
|
275
|
+
if processedValue != value
|
276
|
+
nextCallback = -> runCallback(value)
|
277
|
+
timer?.cancel()
|
278
|
+
timer = u.promiseTimer(delay)
|
279
|
+
# We wait until both the delay has passed and a previous callback is done executing
|
280
|
+
$.when(timer, lastCallbackDone).then(nextCallback)
|
298
281
|
|
299
282
|
# Although (depending on the browser) we only need/receive either input or change,
|
300
283
|
# we always bind to both events in case another script manually triggers it.
|
@@ -307,12 +290,10 @@ up.form = (($) ->
|
|
307
290
|
|
308
291
|
$field.on(changeEvents, check)
|
309
292
|
|
310
|
-
check()
|
311
|
-
|
312
293
|
# return destructor
|
313
294
|
return ->
|
314
295
|
$field.off(changeEvents, check)
|
315
|
-
|
296
|
+
timer?.cancel()
|
316
297
|
|
317
298
|
###*
|
318
299
|
[Observes](/up.observe) a field or form and submits the form when a value changes.
|
@@ -860,7 +841,7 @@ up.form = (($) ->
|
|
860
841
|
but not if the checkbox was changed:
|
861
842
|
|
862
843
|
<form method="GET" action="/search">
|
863
|
-
<input type="search" name="query" autosubmit>
|
844
|
+
<input type="search" name="query" up-autosubmit>
|
864
845
|
<input type="checkbox"> Include archive
|
865
846
|
</form>
|
866
847
|
|
@@ -778,6 +778,7 @@ up.util = (($) ->
|
|
778
778
|
setTimeout(callback, millis)
|
779
779
|
else
|
780
780
|
callback()
|
781
|
+
undefined
|
781
782
|
|
782
783
|
|
783
784
|
###*
|
@@ -1777,14 +1778,21 @@ up.util = (($) ->
|
|
1777
1778
|
The proxy's `.promise` attribute is available even before the function is called
|
1778
1779
|
and will resolve when the inner function's returned promise resolves.
|
1779
1780
|
|
1781
|
+
If the inner function does not return a promise, the proxy's `.promise` attribute
|
1782
|
+
will resolve as soon as the inner function returns.
|
1783
|
+
|
1780
1784
|
@function up.util.previewable
|
1781
1785
|
@internal
|
1782
1786
|
###
|
1783
1787
|
previewable = (fun) ->
|
1784
1788
|
deferred = $.Deferred()
|
1785
1789
|
preview = (args...) ->
|
1786
|
-
fun(args...)
|
1787
|
-
|
1790
|
+
funValue = fun(args...)
|
1791
|
+
if isPromise(funValue)
|
1792
|
+
funValue.then -> deferred.resolve(funValue)
|
1793
|
+
else
|
1794
|
+
deferred.resolve(funValue)
|
1795
|
+
funValue
|
1788
1796
|
preview.promise = deferred.promise()
|
1789
1797
|
preview
|
1790
1798
|
|
@@ -1844,6 +1852,27 @@ up.util = (($) ->
|
|
1844
1852
|
->
|
1845
1853
|
map functions, (f) -> f()
|
1846
1854
|
|
1855
|
+
# ###*
|
1856
|
+
# @function up.util.race
|
1857
|
+
# @internal
|
1858
|
+
# ###
|
1859
|
+
# race = (promises...) ->
|
1860
|
+
# raceDone = $.Deferred()
|
1861
|
+
# each promises, (promise) ->
|
1862
|
+
# promise.then -> raceDone.resolve()
|
1863
|
+
# raceDone.promise()
|
1864
|
+
|
1865
|
+
###*
|
1866
|
+
@function up.util.promiseTimer
|
1867
|
+
@internal
|
1868
|
+
###
|
1869
|
+
promiseTimer = (ms) ->
|
1870
|
+
deferred = $.Deferred()
|
1871
|
+
timeout = setTimer ms, ->
|
1872
|
+
deferred.resolve()
|
1873
|
+
deferred.cancel = -> clearTimeout(timeout)
|
1874
|
+
deferred
|
1875
|
+
|
1847
1876
|
isDetached: isDetached
|
1848
1877
|
requestDataAsArray: requestDataAsArray
|
1849
1878
|
requestDataAsQuery: requestDataAsQuery
|
@@ -1952,6 +1981,8 @@ up.util = (($) ->
|
|
1952
1981
|
DivertibleChain: DivertibleChain
|
1953
1982
|
submittedValue: submittedValue
|
1954
1983
|
sequence: sequence
|
1984
|
+
promiseTimer: promiseTimer
|
1985
|
+
previewable: previewable
|
1955
1986
|
|
1956
1987
|
)($)
|
1957
1988
|
|
data/lib/unpoly/rails/version.rb
CHANGED
data/spec_app/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
unpoly-rails (0.
|
4
|
+
unpoly-rails (0.30.0)
|
5
5
|
rails (>= 3)
|
6
6
|
|
7
7
|
GEM
|
@@ -82,8 +82,8 @@ GEM
|
|
82
82
|
hpricot (~> 0.8.6)
|
83
83
|
ruby_parser (~> 3.1.1)
|
84
84
|
i18n (0.7.0)
|
85
|
-
jasmine-core (2.
|
86
|
-
jasmine-rails (0.
|
85
|
+
jasmine-core (2.5.2)
|
86
|
+
jasmine-rails (0.14.1)
|
87
87
|
jasmine-core (>= 1.3, < 3.0)
|
88
88
|
phantomjs (>= 1.9)
|
89
89
|
railties (>= 3.2.0)
|
@@ -99,12 +99,14 @@ GEM
|
|
99
99
|
mail (2.6.3)
|
100
100
|
mime-types (>= 1.16, < 3)
|
101
101
|
mime-types (2.99)
|
102
|
-
mini_portile2 (2.
|
103
|
-
minitest (5.
|
104
|
-
multi_json (1.
|
105
|
-
nokogiri (1.6.
|
106
|
-
mini_portile2 (~> 2.
|
107
|
-
|
102
|
+
mini_portile2 (2.1.0)
|
103
|
+
minitest (5.9.1)
|
104
|
+
multi_json (1.12.1)
|
105
|
+
nokogiri (1.6.8)
|
106
|
+
mini_portile2 (~> 2.1.0)
|
107
|
+
pkg-config (~> 1.1.7)
|
108
|
+
phantomjs (2.1.1.0)
|
109
|
+
pkg-config (1.1.7)
|
108
110
|
rack (1.6.4)
|
109
111
|
rack-test (0.6.3)
|
110
112
|
rack (>= 1.0)
|
@@ -132,7 +134,7 @@ GEM
|
|
132
134
|
activesupport (= 4.2.0)
|
133
135
|
rake (>= 0.8.7)
|
134
136
|
thor (>= 0.18.1, < 2.0)
|
135
|
-
rake (11.
|
137
|
+
rake (11.3.0)
|
136
138
|
ref (1.0.5)
|
137
139
|
rspec-core (3.4.1)
|
138
140
|
rspec-support (~> 3.4.0)
|
@@ -3,7 +3,7 @@ describe 'up.form', ->
|
|
3
3
|
u = up.util
|
4
4
|
|
5
5
|
describe 'Javascript functions', ->
|
6
|
-
|
6
|
+
|
7
7
|
describe 'up.observe', ->
|
8
8
|
|
9
9
|
beforeEach ->
|
@@ -23,43 +23,100 @@ describe 'up.form', ->
|
|
23
23
|
|
24
24
|
u.each changeEvents, (eventName) ->
|
25
25
|
|
26
|
-
|
27
|
-
$input = affix('input[value="old-value"]')
|
28
|
-
callback = jasmine.createSpy('change callback')
|
29
|
-
up.observe($input, callback)
|
30
|
-
$input.val('new-value')
|
31
|
-
u.times 2, -> $input.trigger(eventName)
|
32
|
-
u.nextFrame ->
|
33
|
-
expect(callback).toHaveBeenCalledWith('new-value', $input)
|
34
|
-
expect(callback.calls.count()).toEqual(1)
|
35
|
-
done()
|
26
|
+
describe "when the input receives a #{eventName} event", ->
|
36
27
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
28
|
+
it "runs the callback if the value changed", (done) ->
|
29
|
+
$input = affix('input[value="old-value"]')
|
30
|
+
callback = jasmine.createSpy('change callback')
|
31
|
+
up.observe($input, callback)
|
32
|
+
$input.val('new-value')
|
33
|
+
u.times 2, -> $input.trigger(eventName)
|
34
|
+
u.nextFrame ->
|
35
|
+
expect(callback).toHaveBeenCalledWith('new-value', $input)
|
36
|
+
expect(callback.calls.count()).toEqual(1)
|
37
|
+
done()
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
39
|
+
it "does not run the callback if the value didn't change", (done) ->
|
40
|
+
$input = affix('input[value="old-value"]')
|
41
|
+
callback = jasmine.createSpy('change callback')
|
42
|
+
up.observe($input, callback)
|
43
|
+
$input.trigger(eventName)
|
44
|
+
u.nextFrame ->
|
45
|
+
expect(callback).not.toHaveBeenCalled()
|
46
|
+
done()
|
53
47
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
48
|
+
it 'debounces the callback when the { delay } option is given', (done) ->
|
49
|
+
$input = affix('input[value="old-value"]')
|
50
|
+
callback = jasmine.createSpy('change callback')
|
51
|
+
up.observe($input, { delay: 100 }, callback)
|
52
|
+
$input.val('new-value-1')
|
53
|
+
$input.trigger(eventName)
|
54
|
+
u.setTimer 50, ->
|
55
|
+
# 50 ms after change 1: We're still waiting for the 100ms delay to expire
|
56
|
+
expect(callback.calls.count()).toEqual(0)
|
57
|
+
u.setTimer 100, ->
|
58
|
+
# 150 ms after change 1: The 100ms delay has expired
|
59
|
+
expect(callback.calls.count()).toEqual(1)
|
60
|
+
expect(callback.calls.mostRecent().args[0]).toEqual('new-value-1')
|
61
|
+
$input.val('new-value-2')
|
62
|
+
$input.trigger(eventName)
|
63
|
+
u.setTimer 40, ->
|
64
|
+
# 40 ms after change 2: We change again, resetting the delay
|
65
|
+
expect(callback.calls.count()).toEqual(1)
|
66
|
+
$input.val('new-value-3')
|
67
|
+
$input.trigger(eventName)
|
68
|
+
u.setTimer 85, ->
|
69
|
+
# 125 ms after change 2, which was superseded by change 3
|
70
|
+
# 85 ms after change 3
|
71
|
+
expect(callback.calls.count()).toEqual(1)
|
72
|
+
u.setTimer 65, ->
|
73
|
+
# 190 ms after change 2, which was superseded by change 3
|
74
|
+
# 150 ms after change 3
|
75
|
+
expect(callback.calls.count()).toEqual(2)
|
76
|
+
expect(callback.calls.mostRecent().args[0]).toEqual('new-value-3')
|
77
|
+
done()
|
78
|
+
|
79
|
+
it 'delays a callback if a previous async callback is taking long to execute', (done) ->
|
80
|
+
$input = affix('input[value="old-value"]')
|
81
|
+
callbackCount = 0
|
82
|
+
callback = ->
|
83
|
+
callbackCount += 1
|
84
|
+
u.promiseTimer(100)
|
85
|
+
up.observe($input, { delay: 1 }, callback)
|
86
|
+
$input.val('new-value-1')
|
87
|
+
$input.trigger(eventName)
|
88
|
+
u.setTimer 30, ->
|
89
|
+
# Callback has been called and takes 100 ms to complete
|
90
|
+
expect(callbackCount).toEqual(1)
|
91
|
+
$input.val('new-value-2')
|
92
|
+
$input.trigger(eventName)
|
93
|
+
u.setTimer 30, ->
|
94
|
+
# Second callback is triggerd, but waits for first callback to complete
|
95
|
+
expect(callbackCount).toEqual(1)
|
96
|
+
u.setTimer 100, ->
|
97
|
+
expect(callbackCount).toEqual(2)
|
98
|
+
done()
|
99
|
+
|
100
|
+
it 'does not run multiple callbacks if a long-running callback has been blocking multiple subsequent callbacks'
|
101
|
+
|
102
|
+
it "runs a callback in the same frame if the delay is 0", ->
|
103
|
+
console.debug('*** next example')
|
104
|
+
$input = affix('input[value="old-value"]')
|
105
|
+
callback = jasmine.createSpy('change callback')
|
106
|
+
up.observe($input, { delay: 0 }, callback)
|
107
|
+
$input.val('new-value')
|
108
|
+
$input.trigger(eventName)
|
109
|
+
expect(callback.calls.count()).toEqual(1)
|
110
|
+
|
111
|
+
it "runs multiple callbacks in the same frame if the delay is 0", ->
|
112
|
+
$input = affix('input[value="old-value"]')
|
113
|
+
callback = jasmine.createSpy('change callback')
|
114
|
+
up.observe($input, { delay: 0 }, callback)
|
115
|
+
$input.val('new-value')
|
116
|
+
$input.trigger(eventName)
|
117
|
+
$input.val('yet-another-value')
|
118
|
+
$input.trigger(eventName)
|
119
|
+
expect(callback.calls.count()).toEqual(2)
|
63
120
|
|
64
121
|
describe 'when the first argument is a checkbox', ->
|
65
122
|
|
@@ -163,42 +220,44 @@ describe 'up.form', ->
|
|
163
220
|
|
164
221
|
u.each changeEvents, (eventName) ->
|
165
222
|
|
166
|
-
|
167
|
-
$form = affix('form')
|
168
|
-
$input = $form.affix('input[value="old-value"]')
|
169
|
-
callback = jasmine.createSpy('change callback')
|
170
|
-
up.observe($form, callback)
|
171
|
-
$input.val('new-value')
|
172
|
-
u.times 2, -> $input.trigger(eventName)
|
173
|
-
u.nextFrame ->
|
174
|
-
expect(callback).toHaveBeenCalledWith('new-value', $input)
|
175
|
-
expect(callback.calls.count()).toEqual(1)
|
176
|
-
done()
|
223
|
+
describe "when any of the form's inputs receives a #{eventName} event", ->
|
177
224
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
225
|
+
it "runs the callback if the value changed", (done) ->
|
226
|
+
$form = affix('form')
|
227
|
+
$input = $form.affix('input[value="old-value"]')
|
228
|
+
callback = jasmine.createSpy('change callback')
|
229
|
+
up.observe($form, callback)
|
230
|
+
$input.val('new-value')
|
231
|
+
u.times 2, -> $input.trigger(eventName)
|
232
|
+
u.nextFrame ->
|
233
|
+
expect(callback).toHaveBeenCalledWith('new-value', $input)
|
234
|
+
expect(callback.calls.count()).toEqual(1)
|
235
|
+
done()
|
187
236
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
237
|
+
it "does not run the callback if the value didn't change", (done) ->
|
238
|
+
$form = affix('form')
|
239
|
+
$input = $form.affix('input[value="old-value"]')
|
240
|
+
callback = jasmine.createSpy('change callback')
|
241
|
+
up.observe($form, callback)
|
242
|
+
$input.trigger(eventName)
|
243
|
+
u.nextFrame ->
|
244
|
+
expect(callback).not.toHaveBeenCalled()
|
245
|
+
done()
|
246
|
+
|
247
|
+
# it 'runs the callback only once when a radio button group changes its selection', ->
|
248
|
+
# $form = affix('form')
|
249
|
+
# $radio1 = $form.affix('input[type="radio"][name="group"][value="1"][checked="checked"]')
|
250
|
+
# $radio2 = $form.affix('input[type="radio"][name="group"][value="2"]')
|
251
|
+
# callback = jasmine.createSpy('change callback')
|
252
|
+
# up.observe($form, callback)
|
253
|
+
# $radio2.get(0).click()
|
254
|
+
# u.nextFrame ->
|
255
|
+
# expect(callback.calls.count()).toEqual(1)
|
197
256
|
|
198
257
|
describe 'up.submit', ->
|
199
258
|
|
200
259
|
describeCapability 'canPushState', ->
|
201
|
-
|
260
|
+
|
202
261
|
beforeEach ->
|
203
262
|
@$form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
|
204
263
|
@$form.append('<input name="field1" value="value1">')
|
@@ -232,11 +291,11 @@ describe 'up.form', ->
|
|
232
291
|
responseText:
|
233
292
|
"""
|
234
293
|
text-before
|
235
|
-
|
294
|
+
|
236
295
|
<form>
|
237
296
|
error-messages
|
238
297
|
</form>
|
239
|
-
|
298
|
+
|
240
299
|
text-after
|
241
300
|
"""
|
242
301
|
expect(up.browser.url()).toEqual(@hrefBeforeExample)
|
@@ -300,12 +359,12 @@ describe 'up.form', ->
|
|
300
359
|
expect(form.submit).toHaveBeenCalled()
|
301
360
|
|
302
361
|
describeFallback 'canPushState', ->
|
303
|
-
|
362
|
+
|
304
363
|
it 'falls back to a vanilla form submission', ->
|
305
364
|
$form = affix('form[action="/path/to"][method="put"][up-target=".response"]')
|
306
365
|
form = $form.get(0)
|
307
366
|
spyOn(form, 'submit')
|
308
|
-
|
367
|
+
|
309
368
|
up.submit($form)
|
310
369
|
expect(form.submit).toHaveBeenCalled()
|
311
370
|
|
@@ -358,7 +417,10 @@ describe 'up.form', ->
|
|
358
417
|
|
359
418
|
describe '[up-observe]', ->
|
360
419
|
|
361
|
-
|
420
|
+
afterEach ->
|
421
|
+
window.observeCallbackSpy = undefined
|
422
|
+
|
423
|
+
it 'runs the Javascript code in the attribute value when a change is observed in the field', (done) ->
|
362
424
|
$form = affix('form')
|
363
425
|
window.observeCallbackSpy = jasmine.createSpy('observe callback')
|
364
426
|
$field = $form.affix('input[val="old-value"][up-observe="window.observeCallbackSpy(value, $field.get(0))"]')
|
@@ -369,6 +431,20 @@ describe 'up.form', ->
|
|
369
431
|
expect(window.observeCallbackSpy).toHaveBeenCalledWith('new-value', $field.get(0))
|
370
432
|
done()
|
371
433
|
|
434
|
+
describe 'with [up-delay] modifier', ->
|
435
|
+
|
436
|
+
it 'debounces the callback', (done) ->
|
437
|
+
$form = affix('form')
|
438
|
+
window.observeCallbackSpy = jasmine.createSpy('observe callback')
|
439
|
+
$field = $form.affix('input[val="old-value"][up-observe="window.observeCallbackSpy()"][up-delay="50"]')
|
440
|
+
up.hello($form)
|
441
|
+
$field.val('new-value')
|
442
|
+
$field.trigger('change')
|
443
|
+
u.nextFrame ->
|
444
|
+
expect(window.observeCallbackSpy).not.toHaveBeenCalled()
|
445
|
+
u.setTimer 80, ->
|
446
|
+
expect(window.observeCallbackSpy).toHaveBeenCalled()
|
447
|
+
done()
|
372
448
|
|
373
449
|
describe 'input[up-validate]', ->
|
374
450
|
|
@@ -1,7 +1,85 @@
|
|
1
1
|
describe 'up.util', ->
|
2
|
-
|
2
|
+
|
3
|
+
u = up.util
|
4
|
+
|
3
5
|
describe 'Javascript functions', ->
|
4
6
|
|
7
|
+
describe 'up.util.previewable', ->
|
8
|
+
|
9
|
+
it 'wraps a function into a proxy function with an additional .promise attribute', ->
|
10
|
+
fun = -> 'return value'
|
11
|
+
proxy = up.util.previewable(fun)
|
12
|
+
expect(u.isFunction(proxy)).toBe(true)
|
13
|
+
expect(u.isPromise(proxy.promise)).toBe(true)
|
14
|
+
expect(proxy()).toEqual('return value')
|
15
|
+
|
16
|
+
it "resolves the proxy's .promise when the inner function returns", (done) ->
|
17
|
+
fun = -> 'return value'
|
18
|
+
proxy = up.util.previewable(fun)
|
19
|
+
callback = jasmine.createSpy('promise callback')
|
20
|
+
proxy.promise.then(callback)
|
21
|
+
u.nextFrame ->
|
22
|
+
expect(callback).not.toHaveBeenCalled()
|
23
|
+
proxy()
|
24
|
+
u.nextFrame ->
|
25
|
+
expect(callback).toHaveBeenCalledWith('return value')
|
26
|
+
done()
|
27
|
+
|
28
|
+
it "delays resolution of the proxy's .promise if the inner function returns a promise", (done) ->
|
29
|
+
funDeferred = $.Deferred()
|
30
|
+
fun = -> funDeferred
|
31
|
+
proxy = up.util.previewable(fun)
|
32
|
+
callback = jasmine.createSpy('promise callback')
|
33
|
+
proxy.promise.then(callback)
|
34
|
+
proxy()
|
35
|
+
u.nextFrame ->
|
36
|
+
expect(callback).not.toHaveBeenCalled()
|
37
|
+
funDeferred.resolve()
|
38
|
+
u.nextFrame ->
|
39
|
+
expect(callback).toHaveBeenCalled()
|
40
|
+
done()
|
41
|
+
|
42
|
+
describe 'up.util.DivertibleChain', ->
|
43
|
+
|
44
|
+
it "instantiates a task queue whose (2..n)th tasks can be changed by calling '.asap'", (done) ->
|
45
|
+
chain = new up.util.DivertibleChain()
|
46
|
+
|
47
|
+
timer1Spy = jasmine.createSpy('timer1 has been called')
|
48
|
+
timer1 = ->
|
49
|
+
timer1Spy()
|
50
|
+
u.promiseTimer(50)
|
51
|
+
|
52
|
+
timer2Spy = jasmine.createSpy('timer2 has been called')
|
53
|
+
timer2 = ->
|
54
|
+
timer2Spy()
|
55
|
+
u.promiseTimer(50)
|
56
|
+
|
57
|
+
timer3Spy = jasmine.createSpy('timer3 has been called')
|
58
|
+
timer3 = ->
|
59
|
+
timer3Spy()
|
60
|
+
u.promiseTimer(50)
|
61
|
+
|
62
|
+
timer4Spy = jasmine.createSpy('timer4 has been called')
|
63
|
+
timer4 = ->
|
64
|
+
timer4Spy()
|
65
|
+
u.promiseTimer(50)
|
66
|
+
|
67
|
+
chain.asap(timer1)
|
68
|
+
u.nextFrame ->
|
69
|
+
expect(timer1Spy).toHaveBeenCalled()
|
70
|
+
chain.asap(timer2)
|
71
|
+
u.nextFrame ->
|
72
|
+
# timer2 is still waiting for timer1 to finish
|
73
|
+
expect(timer2Spy).not.toHaveBeenCalled()
|
74
|
+
# Override the (2..n)th tasks. This unschedules timer2.
|
75
|
+
chain.asap(timer3, timer4)
|
76
|
+
u.setTimer 80, ->
|
77
|
+
expect(timer2Spy).not.toHaveBeenCalled()
|
78
|
+
expect(timer3Spy).toHaveBeenCalled()
|
79
|
+
u.setTimer 70, ->
|
80
|
+
expect(timer4Spy).toHaveBeenCalled()
|
81
|
+
done()
|
82
|
+
|
5
83
|
describe 'up.util.sequence', ->
|
6
84
|
|
7
85
|
it 'combines the given functions into a single function', ->
|
@@ -144,10 +222,17 @@ describe 'up.util', ->
|
|
144
222
|
jasmine.clock().tick(1500)
|
145
223
|
expect(callback).toHaveBeenCalled()
|
146
224
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
225
|
+
describe 'if the delay is zero', ->
|
226
|
+
|
227
|
+
it 'calls the given function in the current execution frame', ->
|
228
|
+
callback = jasmine.createSpy()
|
229
|
+
up.util.setTimer(0, callback)
|
230
|
+
expect(callback).toHaveBeenCalled()
|
231
|
+
|
232
|
+
it "returns undefined so the return value won't be mistaken with a Javascript timer ID", ->
|
233
|
+
callback = -> 'function return value'
|
234
|
+
timerReturnValue = up.util.setTimer(0, callback)
|
235
|
+
expect(timerReturnValue).toBeUndefined()
|
151
236
|
|
152
237
|
# describe 'up.util.argNames', ->
|
153
238
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: unpoly-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.30.
|
4
|
+
version: 0.30.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|