upjs-rails 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.flow.implant('.foo', "<div class='foo'>new text</div>")
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.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
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.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
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.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
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.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
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.flow.implant('.foo', "<div class='foo'>new text</div>")
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.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.inside'))
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.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.inside'))
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.flow.implant('.outside', "<div class='outside'>new outside</div>", origin: $('.outside'))
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.flow.implant('.inside', "<div class='inside'>new inside</div>", origin: $('.outside'))
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.proxy.ajax', ->
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.proxy.ajax(url: '/foo').then (data) -> responses.push(data)
17
+ up.ajax(url: '/foo').then (data) -> responses.push(data)
18
18
  jasmine.clock().tick(3 * 60 * 1000)
19
- up.proxy.ajax(url: '/foo').then (data) -> responses.push(data)
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.proxy.ajax(url: '/foo').then (data) -> responses.push(data)
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.proxy.ajax(url: '/path', target: '.a')
45
- up.proxy.ajax(url: '/path', target: '.b')
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.proxy.ajax(url: '/path', target: 'html')
50
- up.proxy.ajax(url: '/path', target: 'body')
51
- up.proxy.ajax(url: '/path', target: 'p')
52
- up.proxy.ajax(url: '/path', target: '.klass')
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.proxy.ajax(url: '/path', target: 'body')
57
- up.proxy.ajax(url: '/path', target: 'p')
58
- up.proxy.ajax(url: '/path', target: '.klass')
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.proxy.ajax(url: '/path', target: 'body')
63
- up.proxy.ajax(url: '/path', target: 'html')
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.proxy.ajax(url: '/foo')
68
- up.proxy.ajax(url: '/bar')
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.proxy.ajax(url: '/foo', method: method)
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.proxy.ajax(url: '/foo', method: method, cache: false)
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.proxy.ajax(url: '/foo', method: method)
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.proxy.ajax(url: '/foo', method: method, cache: true)
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/foo', method: method)
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.proxy.ajax(url: '/foo', method: method)
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.proxy.ajax(url: '/foo').then (html) -> responses.push(html)
144
- up.proxy.ajax(url: '/bar').then (html) -> responses.push(html)
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.proxy.ajax(url: '/foo', preload: true)
154
- # up.proxy.ajax(url: '/bar')
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/bar')
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.proxy.ajax(url: '/foo', preload: true)
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/foo')
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.proxy.ajax(url: '/foo')
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
- it 'lets allows initializers return a destructor function, which is called when a compiled fragment gets destroyed', ->
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.requestDataAsQueryString', ->
207
+ describe 'up.util.requestDataAsQuery', ->
174
208
 
175
- it 'returns the query section for the given object, including the question mark', ->
176
- string = up.util.requestDataAsQueryString('foo-key': 'foo value', 'bar-key': 'bar value')
177
- expect(string).toEqual('?foo-key=foo%20value&bar-key=bar%20value')
209
+ encodedOpeningBracket = '%5B'
210
+ encodedClosingBracket = '%5D'
211
+ encodedSpace = '%20'
178
212
 
179
- it 'returns an empty string', ->
180
- string = up.util.requestDataAsQueryString({})
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
+ ])