upjs-rails 0.18.1 → 0.19.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/dist/up.js +906 -453
- data/dist/up.min.js +3 -2
- data/lib/assets/javascripts/up/browser.js.coffee +3 -1
- data/lib/assets/javascripts/up/flow.js.coffee +277 -67
- data/lib/assets/javascripts/up/log.js.coffee +1 -0
- data/lib/assets/javascripts/up/motion.js.coffee +12 -3
- data/lib/assets/javascripts/up/proxy.js.coffee +8 -5
- data/lib/assets/javascripts/up/syntax.js.coffee +41 -57
- data/lib/assets/javascripts/up/util.js.coffee +38 -21
- data/lib/upjs/rails/version.rb +1 -1
- data/spec_app/Gemfile.lock +1 -4
- data/spec_app/spec/javascripts/helpers/reset_up.js.coffee +1 -2
- data/spec_app/spec/javascripts/helpers/to_be_blank.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_given.js.coffee +5 -0
- data/spec_app/spec/javascripts/helpers/to_be_missing.js.coffee +5 -0
- data/spec_app/spec/javascripts/up/flow_spec.js.coffee +269 -18
- data/spec_app/spec/javascripts/up/modal_spec.js.coffee +5 -5
- data/spec_app/spec/javascripts/up/popup_spec.js.coffee +5 -5
- data/spec_app/spec/javascripts/up/proxy_spec.js.coffee +36 -36
- data/spec_app/spec/javascripts/up/syntax_spec.js.coffee +43 -2
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +150 -6
- metadata +5 -2
@@ -209,7 +209,7 @@ describe 'up.modal', ->
|
|
209
209
|
$outside = affix('.foo').text('old outside')
|
210
210
|
up.modal.visit('/path', target: '.foo')
|
211
211
|
@respondWith("<div class='foo'>old inside</div>")
|
212
|
-
up.
|
212
|
+
up.extract('.foo', "<div class='foo'>new text</div>")
|
213
213
|
expect($outside).toBeInDOM()
|
214
214
|
expect($outside).toHaveText('old outside')
|
215
215
|
expect($('.up-modal-content')).toHaveText('new text')
|
@@ -218,7 +218,7 @@ describe 'up.modal', ->
|
|
218
218
|
affix('.outside').text('old outside')
|
219
219
|
up.modal.visit('/path', target: '.inside')
|
220
220
|
@respondWith("<div class='inside'>old inside</div>")
|
221
|
-
up.
|
221
|
+
up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
|
222
222
|
expect($('.outside')).toHaveText('new outside')
|
223
223
|
expect($('.up-modal')).not.toExist()
|
224
224
|
|
@@ -226,7 +226,7 @@ describe 'up.modal', ->
|
|
226
226
|
affix('.outside').text('old outside')
|
227
227
|
up.modal.visit('/path', target: '.inside')
|
228
228
|
@respondWith("<div class='inside'>old inside</div>")
|
229
|
-
up.
|
229
|
+
up.extract('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
|
230
230
|
expect($('.inside')).toHaveText('new inside')
|
231
231
|
expect($('.up-modal')).toExist()
|
232
232
|
|
@@ -234,7 +234,7 @@ describe 'up.modal', ->
|
|
234
234
|
affix('.outside').text('old outside')
|
235
235
|
up.modal.visit('/path', target: '.inside')
|
236
236
|
@respondWith("<div class='inside'>old inside</div>")
|
237
|
-
up.
|
237
|
+
up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
|
238
238
|
expect($('.outside')).toHaveText('new outside')
|
239
239
|
expect($('.up-modal')).toExist()
|
240
240
|
|
@@ -242,7 +242,7 @@ describe 'up.modal', ->
|
|
242
242
|
affix('.outside').text('old outside')
|
243
243
|
up.modal.visit('/path', target: '.inside')
|
244
244
|
@respondWith("<div class='inside'>old inside</div>")
|
245
|
-
up.
|
245
|
+
up.extract('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
|
246
246
|
expect($('.inside')).toHaveText('new inside')
|
247
247
|
expect($('.up-modal')).toExist()
|
248
248
|
|
@@ -178,7 +178,7 @@ describe 'up.popup', ->
|
|
178
178
|
$link = affix('.link')
|
179
179
|
up.popup.attach($link, href: '/path', target: '.foo')
|
180
180
|
@respondWith("<div class='foo'>old inside</div>")
|
181
|
-
up.
|
181
|
+
up.extract('.foo', "<div class='foo'>new text</div>")
|
182
182
|
expect($outside).toBeInDOM()
|
183
183
|
expect($outside).toHaveText('old outside')
|
184
184
|
expect($('.up-popup')).toHaveText('new text')
|
@@ -188,7 +188,7 @@ describe 'up.popup', ->
|
|
188
188
|
$link = affix('.link')
|
189
189
|
up.popup.attach($link, href: '/path', target: '.inside')
|
190
190
|
@respondWith("<div class='inside'>old inside</div>")
|
191
|
-
up.
|
191
|
+
up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
|
192
192
|
expect($('.outside')).toHaveText('new outside')
|
193
193
|
expect($('.up-popup')).not.toExist()
|
194
194
|
|
@@ -197,7 +197,7 @@ describe 'up.popup', ->
|
|
197
197
|
$link = affix('.link')
|
198
198
|
up.popup.attach($link, href: '/path', target: '.inside')
|
199
199
|
@respondWith("<div class='inside'>old inside</div>")
|
200
|
-
up.
|
200
|
+
up.extract('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
|
201
201
|
expect($('.inside')).toHaveText('new inside')
|
202
202
|
expect($('.up-popup')).toExist()
|
203
203
|
|
@@ -206,7 +206,7 @@ describe 'up.popup', ->
|
|
206
206
|
$link = affix('.link')
|
207
207
|
up.popup.attach($link, href: '/path', target: '.inside')
|
208
208
|
@respondWith("<div class='inside'>old inside</div>")
|
209
|
-
up.
|
209
|
+
up.extract('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
|
210
210
|
expect($('.outside')).toHaveText('new outside')
|
211
211
|
expect($('.up-popup')).toExist()
|
212
212
|
|
@@ -215,6 +215,6 @@ describe 'up.popup', ->
|
|
215
215
|
$link = affix('.link')
|
216
216
|
up.popup.attach($link, href: '/path', target: '.inside')
|
217
217
|
@respondWith("<div class='inside'>old inside</div>")
|
218
|
-
up.
|
218
|
+
up.extract('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
|
219
219
|
expect($('.inside')).toHaveText('new inside')
|
220
220
|
expect($('.up-popup')).toExist()
|
@@ -8,15 +8,15 @@ describe 'up.proxy', ->
|
|
8
8
|
jasmine.clock().install()
|
9
9
|
jasmine.clock().mockDate()
|
10
10
|
|
11
|
-
describe 'up.
|
11
|
+
describe 'up.ajax', ->
|
12
12
|
|
13
13
|
it 'caches server responses for 5 minutes', ->
|
14
14
|
responses = []
|
15
15
|
|
16
16
|
# Send the same request for the same path, 3 minutes apart
|
17
|
-
up.
|
17
|
+
up.ajax(url: '/foo').then (data) -> responses.push(data)
|
18
18
|
jasmine.clock().tick(3 * 60 * 1000)
|
19
|
-
up.
|
19
|
+
up.ajax(url: '/foo').then (data) -> responses.push(data)
|
20
20
|
|
21
21
|
# See that only a single network request was triggered
|
22
22
|
expect(jasmine.Ajax.requests.count()).toEqual(1)
|
@@ -31,7 +31,7 @@ describe 'up.proxy', ->
|
|
31
31
|
# The clock is now a total of 6 minutes after the first request,
|
32
32
|
# exceeding the cache's retention time of 5 minutes.
|
33
33
|
jasmine.clock().tick(3 * 60 * 1000)
|
34
|
-
up.
|
34
|
+
up.ajax(url: '/foo').then (data) -> responses.push(data)
|
35
35
|
|
36
36
|
# See that we have triggered a second request
|
37
37
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
@@ -41,63 +41,63 @@ describe 'up.proxy', ->
|
|
41
41
|
expect(responses).toEqual(['foo', 'foo', 'bar'])
|
42
42
|
|
43
43
|
it "doesn't reuse responses when asked for the same path, but different selectors", ->
|
44
|
-
up.
|
45
|
-
up.
|
44
|
+
up.ajax(url: '/path', target: '.a')
|
45
|
+
up.ajax(url: '/path', target: '.b')
|
46
46
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
47
47
|
|
48
48
|
it "reuses a response for an 'html' selector when asked for the same path and any other selector", ->
|
49
|
-
up.
|
50
|
-
up.
|
51
|
-
up.
|
52
|
-
up.
|
49
|
+
up.ajax(url: '/path', target: 'html')
|
50
|
+
up.ajax(url: '/path', target: 'body')
|
51
|
+
up.ajax(url: '/path', target: 'p')
|
52
|
+
up.ajax(url: '/path', target: '.klass')
|
53
53
|
expect(jasmine.Ajax.requests.count()).toEqual(1)
|
54
54
|
|
55
55
|
it "reuses a response for a 'body' selector when asked for the same path and any other selector other than 'html'", ->
|
56
|
-
up.
|
57
|
-
up.
|
58
|
-
up.
|
56
|
+
up.ajax(url: '/path', target: 'body')
|
57
|
+
up.ajax(url: '/path', target: 'p')
|
58
|
+
up.ajax(url: '/path', target: '.klass')
|
59
59
|
expect(jasmine.Ajax.requests.count()).toEqual(1)
|
60
60
|
|
61
61
|
it "doesn't reuse a response for a 'body' selector when asked for the same path but an 'html' selector", ->
|
62
|
-
up.
|
63
|
-
up.
|
62
|
+
up.ajax(url: '/path', target: 'body')
|
63
|
+
up.ajax(url: '/path', target: 'html')
|
64
64
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
65
65
|
|
66
66
|
it "doesn't reuse responses for different paths", ->
|
67
|
-
up.
|
68
|
-
up.
|
67
|
+
up.ajax(url: '/foo')
|
68
|
+
up.ajax(url: '/bar')
|
69
69
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
70
70
|
|
71
71
|
u.each ['GET', 'HEAD', 'OPTIONS'], (method) ->
|
72
72
|
|
73
73
|
it "caches #{method} requests", ->
|
74
|
-
u.times 2, -> up.
|
74
|
+
u.times 2, -> up.ajax(url: '/foo', method: method)
|
75
75
|
expect(jasmine.Ajax.requests.count()).toEqual(1)
|
76
76
|
|
77
77
|
it "does not cache #{method} requests with cache: false option", ->
|
78
|
-
u.times 2, -> up.
|
78
|
+
u.times 2, -> up.ajax(url: '/foo', method: method, cache: false)
|
79
79
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
80
80
|
|
81
81
|
u.each ['POST', 'PUT', 'DELETE'], (method) ->
|
82
82
|
|
83
83
|
it "does not cache #{method} requests", ->
|
84
|
-
u.times 2, -> up.
|
84
|
+
u.times 2, -> up.ajax(url: '/foo', method: method)
|
85
85
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
86
86
|
|
87
87
|
it "caches #{method} requests with cache: true option", ->
|
88
|
-
u.times 2, -> up.
|
88
|
+
u.times 2, -> up.ajax(url: '/foo', method: method, cache: true)
|
89
89
|
expect(jasmine.Ajax.requests.count()).toEqual(1)
|
90
90
|
|
91
91
|
it 'does not cache responses with a non-200 status code', ->
|
92
92
|
# Send the same request for the same path, 3 minutes apart
|
93
|
-
up.
|
93
|
+
up.ajax(url: '/foo')
|
94
94
|
|
95
95
|
@respondWith
|
96
96
|
status: 500
|
97
97
|
contentType: 'text/html'
|
98
98
|
responseText: 'foo'
|
99
99
|
|
100
|
-
up.
|
100
|
+
up.ajax(url: '/foo')
|
101
101
|
|
102
102
|
expect(jasmine.Ajax.requests.count()).toEqual(2)
|
103
103
|
|
@@ -116,7 +116,7 @@ describe 'up.proxy', ->
|
|
116
116
|
u.each ['GET', 'POST', 'HEAD', 'OPTIONS'], (method) ->
|
117
117
|
|
118
118
|
it "does not change the method of a #{method} request", ->
|
119
|
-
up.
|
119
|
+
up.ajax(url: '/foo', method: method)
|
120
120
|
request = @lastRequest()
|
121
121
|
expect(request.method).toEqual(method)
|
122
122
|
expect(request.data()['_method']).toBeUndefined()
|
@@ -124,7 +124,7 @@ describe 'up.proxy', ->
|
|
124
124
|
u.each ['PUT', 'PATCH', 'DELETE'], (method) ->
|
125
125
|
|
126
126
|
it "turns a #{method} request into a POST request and sends the actual method as a { _method } param", ->
|
127
|
-
up.
|
127
|
+
up.ajax(url: '/foo', method: method)
|
128
128
|
request = @lastRequest()
|
129
129
|
expect(request.method).toEqual('POST')
|
130
130
|
expect(request.data()['_method']).toEqual([method])
|
@@ -140,8 +140,8 @@ describe 'up.proxy', ->
|
|
140
140
|
|
141
141
|
it 'limits the number of concurrent requests', ->
|
142
142
|
responses = []
|
143
|
-
up.
|
144
|
-
up.
|
143
|
+
up.ajax(url: '/foo').then (html) -> responses.push(html)
|
144
|
+
up.ajax(url: '/bar').then (html) -> responses.push(html)
|
145
145
|
expect(jasmine.Ajax.requests.count()).toEqual(1) # only one request was made
|
146
146
|
@respondWith('first response', request: jasmine.Ajax.requests.at(0))
|
147
147
|
expect(responses).toEqual ['first response']
|
@@ -150,8 +150,8 @@ describe 'up.proxy', ->
|
|
150
150
|
expect(responses).toEqual ['first response', 'second response']
|
151
151
|
|
152
152
|
# it 'considers preloading links for the request limit', ->
|
153
|
-
# up.
|
154
|
-
# up.
|
153
|
+
# up.ajax(url: '/foo', preload: true)
|
154
|
+
# up.ajax(url: '/bar')
|
155
155
|
# expect(jasmine.Ajax.requests.count()).toEqual(1)
|
156
156
|
|
157
157
|
describe 'events', ->
|
@@ -165,14 +165,14 @@ describe 'up.proxy', ->
|
|
165
165
|
|
166
166
|
it 'emits an up:proxy:busy event once the proxy started loading, and up:proxy:idle if it is done loading', ->
|
167
167
|
|
168
|
-
up.
|
168
|
+
up.ajax(url: '/foo')
|
169
169
|
|
170
170
|
expect(@events).toEqual([
|
171
171
|
'up:proxy:load',
|
172
172
|
'up:proxy:busy'
|
173
173
|
])
|
174
174
|
|
175
|
-
up.
|
175
|
+
up.ajax(url: '/bar')
|
176
176
|
|
177
177
|
expect(@events).toEqual([
|
178
178
|
'up:proxy:load',
|
@@ -210,14 +210,14 @@ describe 'up.proxy', ->
|
|
210
210
|
|
211
211
|
# A request for preloading preloading purposes
|
212
212
|
# doesn't make us busy.
|
213
|
-
up.
|
213
|
+
up.ajax(url: '/foo', preload: true)
|
214
214
|
expect(@events).toEqual([
|
215
215
|
'up:proxy:load'
|
216
216
|
])
|
217
217
|
expect(up.proxy.busy()).toBe(false)
|
218
218
|
|
219
219
|
# The same request with preloading does make us busy.
|
220
|
-
up.
|
220
|
+
up.ajax(url: '/foo')
|
221
221
|
expect(@events).toEqual([
|
222
222
|
'up:proxy:load',
|
223
223
|
'up:proxy:busy'
|
@@ -241,7 +241,7 @@ describe 'up.proxy', ->
|
|
241
241
|
it 'can delay the up:proxy:busy event to prevent flickering of spinners', ->
|
242
242
|
up.proxy.config.busyDelay = 100
|
243
243
|
|
244
|
-
up.
|
244
|
+
up.ajax(url: '/foo')
|
245
245
|
expect(@events).toEqual([
|
246
246
|
'up:proxy:load'
|
247
247
|
])
|
@@ -272,7 +272,7 @@ describe 'up.proxy', ->
|
|
272
272
|
it 'does not emit up:proxy:idle if a delayed up:proxy:busy was never emitted due to a fast response', ->
|
273
273
|
up.proxy.config.busyDelay = 100
|
274
274
|
|
275
|
-
up.
|
275
|
+
up.ajax(url: '/foo')
|
276
276
|
expect(@events).toEqual([
|
277
277
|
'up:proxy:load'
|
278
278
|
])
|
@@ -293,7 +293,7 @@ describe 'up.proxy', ->
|
|
293
293
|
|
294
294
|
it 'emits up:proxy:idle if a request returned but failed', ->
|
295
295
|
|
296
|
-
up.
|
296
|
+
up.ajax(url: '/foo')
|
297
297
|
|
298
298
|
expect(@events).toEqual([
|
299
299
|
'up:proxy:load',
|
@@ -15,8 +15,7 @@ describe 'up.syntax', ->
|
|
15
15
|
expect(observeClass).not.toHaveBeenCalledWith('container')
|
16
16
|
expect(observeClass).toHaveBeenCalledWith('child')
|
17
17
|
|
18
|
-
|
19
|
-
|
18
|
+
|
20
19
|
destructor = jasmine.createSpy()
|
21
20
|
up.compiler '.child', ($element) ->
|
22
21
|
destructor
|
@@ -50,6 +49,48 @@ describe 'up.syntax', ->
|
|
50
49
|
|
51
50
|
expect(observeArgs).toHaveBeenCalledWith('child', {})
|
52
51
|
|
52
|
+
it 'compiles matching elements one-by-one', ->
|
53
|
+
compiler = jasmine.createSpy('compiler')
|
54
|
+
up.compiler '.foo', ($element) -> compiler($element)
|
55
|
+
$container = affix('.container')
|
56
|
+
$first = $container.affix('.foo.first')
|
57
|
+
$second = $container.affix('.foo.second')
|
58
|
+
up.hello($container)
|
59
|
+
expect(compiler.calls.count()).toEqual(2)
|
60
|
+
expect(compiler).toHaveBeenCalledWith($first)
|
61
|
+
expect(compiler).toHaveBeenCalledWith($second)
|
62
|
+
|
63
|
+
describe 'with { batch } option', ->
|
64
|
+
|
65
|
+
it 'compiles all matching elements at once', ->
|
66
|
+
compiler = jasmine.createSpy('compiler')
|
67
|
+
up.compiler '.foo', { batch: true }, ($element) -> compiler($element)
|
68
|
+
$container = affix('.container')
|
69
|
+
$first = $container.affix('.foo.first')
|
70
|
+
$second = $container.affix('.foo.second')
|
71
|
+
$both = $first.add($second)
|
72
|
+
up.hello($container)
|
73
|
+
expect(compiler.calls.count()).toEqual(1)
|
74
|
+
expect(compiler).toHaveBeenCalledWith($both)
|
75
|
+
|
76
|
+
describe 'with { keep } option', ->
|
77
|
+
|
78
|
+
it 'adds an up-keep attribute to the fragment during compilation', ->
|
79
|
+
|
80
|
+
up.compiler '.foo', { keep: true }, ->
|
81
|
+
up.compiler '.bar', { }, ->
|
82
|
+
up.compiler '.bar', { keep: false }, ->
|
83
|
+
up.compiler '.bam', { keep: '.partner' }, ->
|
84
|
+
|
85
|
+
$foo = up.hello(affix('.foo'))
|
86
|
+
$bar = up.hello(affix('.bar'))
|
87
|
+
$baz = up.hello(affix('.baz'))
|
88
|
+
$bam = up.hello(affix('.bam'))
|
89
|
+
|
90
|
+
expect($foo.attr('up-keep')).toEqual('')
|
91
|
+
expect($bar.attr('up-keep')).toBeMissing()
|
92
|
+
expect($baz.attr('up-keep')).toBeMissing()
|
93
|
+
expect($bam.attr('up-keep')).toEqual('.partner')
|
53
94
|
|
54
95
|
describe 'up.hello', ->
|
55
96
|
|
@@ -87,6 +87,40 @@ describe 'up.util', ->
|
|
87
87
|
$element = affix('div').attr('foo', 'some text')
|
88
88
|
expect(up.util.castedAttr($element, 'foo')).toBe('some text')
|
89
89
|
|
90
|
+
describe 'up.util.any', ->
|
91
|
+
|
92
|
+
it 'returns true if an element in the array returns true for the given function', ->
|
93
|
+
result = up.util.any [null, undefined, 'foo', ''], up.util.isPresent
|
94
|
+
expect(result).toBe(true)
|
95
|
+
|
96
|
+
it 'returns false if no element in the array returns true for the given function', ->
|
97
|
+
result = up.util.any [null, undefined, ''], up.util.isPresent
|
98
|
+
expect(result).toBe(false)
|
99
|
+
|
100
|
+
it 'short-circuits once an element returns true', ->
|
101
|
+
count = 0
|
102
|
+
up.util.any [null, undefined, 'foo', ''], (element) ->
|
103
|
+
count += 1
|
104
|
+
up.util.isPresent(element)
|
105
|
+
expect(count).toBe(3)
|
106
|
+
|
107
|
+
describe 'up.util.all', ->
|
108
|
+
|
109
|
+
it 'returns true if all element in the array returns true for the given function', ->
|
110
|
+
result = up.util.all ['foo', 'bar', 'baz'], up.util.isPresent
|
111
|
+
expect(result).toBe(true)
|
112
|
+
|
113
|
+
it 'returns false if an element in the array returns false for the given function', ->
|
114
|
+
result = up.util.all ['foo', 'bar', null, 'baz'], up.util.isPresent
|
115
|
+
expect(result).toBe(false)
|
116
|
+
|
117
|
+
it 'short-circuits once an element returns false', ->
|
118
|
+
count = 0
|
119
|
+
up.util.all ['foo', 'bar', '', 'baz'], (element) ->
|
120
|
+
count += 1
|
121
|
+
up.util.isPresent(element)
|
122
|
+
expect(count).toBe(3)
|
123
|
+
|
90
124
|
describe 'up.util.isBlank', ->
|
91
125
|
|
92
126
|
it 'returns false for false', ->
|
@@ -170,12 +204,122 @@ describe 'up.util', ->
|
|
170
204
|
object.reset()
|
171
205
|
expect(object.reset).toBeDefined()
|
172
206
|
|
173
|
-
describe 'up.util.
|
207
|
+
describe 'up.util.requestDataAsQuery', ->
|
174
208
|
|
175
|
-
|
176
|
-
|
177
|
-
|
209
|
+
encodedOpeningBracket = '%5B'
|
210
|
+
encodedClosingBracket = '%5D'
|
211
|
+
encodedSpace = '%20'
|
178
212
|
|
179
|
-
it 'returns
|
180
|
-
string = up.util.
|
213
|
+
it 'returns the query section for the given object', ->
|
214
|
+
string = up.util.requestDataAsQuery('foo-key': 'foo value', 'bar-key': 'bar value')
|
215
|
+
expect(string).toEqual("foo-key=foo#{encodedSpace}value&bar-key=bar#{encodedSpace}value")
|
216
|
+
|
217
|
+
it 'returns the query section for the given nested object', ->
|
218
|
+
string = up.util.requestDataAsQuery('foo-key': { 'bar-key': 'bar-value' }, 'bam-key': 'bam-value')
|
219
|
+
expect(string).toEqual("foo-key#{encodedOpeningBracket}bar-key#{encodedClosingBracket}=bar-value&bam-key=bam-value")
|
220
|
+
|
221
|
+
it 'returns the query section for the given array with { name } and { value } keys', ->
|
222
|
+
string = up.util.requestDataAsQuery([
|
223
|
+
{ name: 'foo-key', value: 'foo value' },
|
224
|
+
{ name: 'bar-key', value: 'bar value' }
|
225
|
+
])
|
226
|
+
expect(string).toEqual("foo-key=foo#{encodedSpace}value&bar-key=bar#{encodedSpace}value")
|
227
|
+
|
228
|
+
it 'returns an empty string for an empty object', ->
|
229
|
+
string = up.util.requestDataAsQuery({})
|
230
|
+
expect(string).toEqual('')
|
231
|
+
|
232
|
+
it 'returns an empty string for an empty string', ->
|
233
|
+
string = up.util.requestDataAsQuery('')
|
234
|
+
expect(string).toEqual('')
|
235
|
+
|
236
|
+
it 'returns an empty string for undefined', ->
|
237
|
+
string = up.util.requestDataAsQuery(undefined)
|
181
238
|
expect(string).toEqual('')
|
239
|
+
|
240
|
+
it 'URL-encodes characters in the key and value', ->
|
241
|
+
string = up.util.requestDataAsQuery({ 'äpfel': 'bäume' })
|
242
|
+
expect(string).toEqual('%C3%A4pfel=b%C3%A4ume')
|
243
|
+
|
244
|
+
it 'URL-encodes plus characters', ->
|
245
|
+
string = up.util.requestDataAsQuery({ 'my+key': 'my+value' })
|
246
|
+
expect(string).toEqual('my%2Bkey=my%2Bvalue')
|
247
|
+
|
248
|
+
|
249
|
+
describe 'up.util.requestDataAsArray', ->
|
250
|
+
|
251
|
+
it 'normalized null to an empty array', ->
|
252
|
+
array = up.util.requestDataAsArray(null)
|
253
|
+
expect(array).toEqual([])
|
254
|
+
|
255
|
+
it 'normalized undefined to an empty array', ->
|
256
|
+
array = up.util.requestDataAsArray(undefined)
|
257
|
+
expect(array).toEqual([])
|
258
|
+
|
259
|
+
it 'normalizes an object hash to an array of objects with { name } and { value } keys', ->
|
260
|
+
array = up.util.requestDataAsArray(
|
261
|
+
'foo-key': 'foo-value'
|
262
|
+
'bar-key': 'bar-value'
|
263
|
+
)
|
264
|
+
expect(array).toEqual([
|
265
|
+
{ name: 'foo-key', value: 'foo-value' },
|
266
|
+
{ name: 'bar-key', value: 'bar-value' },
|
267
|
+
])
|
268
|
+
|
269
|
+
it 'normalizes a nested object hash to a flat array using param naming conventions', ->
|
270
|
+
array = up.util.requestDataAsArray(
|
271
|
+
'foo-key': 'foo-value'
|
272
|
+
'bar-key': {
|
273
|
+
'bam-key': 'bam-value'
|
274
|
+
'baz-key': {
|
275
|
+
'qux-key': 'qux-value'
|
276
|
+
}
|
277
|
+
}
|
278
|
+
)
|
279
|
+
expect(array).toEqual([
|
280
|
+
{ name: 'foo-key', value: 'foo-value' },
|
281
|
+
{ name: 'bar-key[bam-key]', value: 'bam-value' },
|
282
|
+
{ name: 'bar-key[baz-key][qux-key]', value: 'qux-value' },
|
283
|
+
])
|
284
|
+
|
285
|
+
it 'returns a given array without modification', ->
|
286
|
+
array = up.util.requestDataAsArray([
|
287
|
+
{ name: 'foo-key', value: 'foo-value' },
|
288
|
+
{ name: 'bar-key', value: 'bar-value' },
|
289
|
+
])
|
290
|
+
expect(array).toEqual([
|
291
|
+
{ name: 'foo-key', value: 'foo-value' },
|
292
|
+
{ name: 'bar-key', value: 'bar-value' },
|
293
|
+
])
|
294
|
+
|
295
|
+
it 'does not URL-encode special characters keys or values', ->
|
296
|
+
array = up.util.requestDataAsArray(
|
297
|
+
'äpfel': { 'bäume': 'börse' }
|
298
|
+
)
|
299
|
+
expect(array).toEqual([
|
300
|
+
{ name: 'äpfel[bäume]', value: 'börse' },
|
301
|
+
])
|
302
|
+
|
303
|
+
it 'does not URL-encode spaces in keys or values', ->
|
304
|
+
array = up.util.requestDataAsArray(
|
305
|
+
'my key': 'my value'
|
306
|
+
)
|
307
|
+
expect(array).toEqual([
|
308
|
+
{ name: 'my key', value: 'my value' },
|
309
|
+
])
|
310
|
+
|
311
|
+
it 'does not URL-encode ampersands in keys or values', ->
|
312
|
+
array = up.util.requestDataAsArray(
|
313
|
+
'my&key': 'my&value'
|
314
|
+
)
|
315
|
+
expect(array).toEqual([
|
316
|
+
{ name: 'my&key', value: 'my&value' },
|
317
|
+
])
|
318
|
+
|
319
|
+
it 'does not URL-encode equal signs in keys or values', ->
|
320
|
+
array = up.util.requestDataAsArray(
|
321
|
+
'my=key': 'my=value'
|
322
|
+
)
|
323
|
+
expect(array).toEqual([
|
324
|
+
{ name: 'my=key', value: 'my=value' },
|
325
|
+
])
|