unpoly-rails 0.54.1 → 0.55.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of unpoly-rails might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/dist/unpoly.js +207 -96
- data/dist/unpoly.min.js +3 -3
- data/lib/assets/javascripts/unpoly/browser.coffee.erb +0 -1
- data/lib/assets/javascripts/unpoly/classes/extract_cascade.coffee +10 -22
- data/lib/assets/javascripts/unpoly/classes/extract_plan.coffee +57 -17
- data/lib/assets/javascripts/unpoly/classes/extract_step.coffee +4 -0
- data/lib/assets/javascripts/unpoly/link.coffee.erb +2 -2
- data/lib/assets/javascripts/unpoly/util.coffee +77 -26
- data/lib/unpoly/rails/version.rb +1 -1
- data/package.json +1 -1
- data/spec_app/Gemfile +1 -0
- data/spec_app/Gemfile.lock +3 -2
- data/spec_app/spec/javascripts/helpers/to_match_text.js.coffee +10 -0
- data/spec_app/spec/javascripts/up/dom_spec.js.coffee +331 -0
- data/spec_app/spec/javascripts/up/radio_spec.js.coffee +22 -0
- data/spec_app/spec/javascripts/up/util_spec.js.coffee +165 -0
- metadata +4 -2
@@ -51,6 +51,28 @@ describe 'up.radio', ->
|
|
51
51
|
promiseState(promise).then (result) ->
|
52
52
|
expect(result.state).toEqual('fulfilled')
|
53
53
|
|
54
|
+
it 'still reveals the element that was originally targeted', asyncSpec (next) ->
|
55
|
+
affix('.hungry[up-hungry]').text('old hungry')
|
56
|
+
affix('.target').text('old target')
|
57
|
+
|
58
|
+
revealStub = up.layout.knife.mock('reveal')
|
59
|
+
|
60
|
+
up.replace('.target', '/path', reveal: true)
|
61
|
+
|
62
|
+
next =>
|
63
|
+
@respondWith """
|
64
|
+
<div class="target">
|
65
|
+
new target
|
66
|
+
</div>
|
67
|
+
"""
|
68
|
+
|
69
|
+
next =>
|
70
|
+
expect(revealStub).toHaveBeenCalled()
|
71
|
+
revealArg = revealStub.calls.mostRecent().args[0]
|
72
|
+
expect(revealArg).not.toBeMatchedBy('.hungry')
|
73
|
+
expect(revealArg).toBeMatchedBy('.target')
|
74
|
+
|
75
|
+
|
54
76
|
it 'does not change the X-Up-Target header for the request', asyncSpec (next) ->
|
55
77
|
affix('.hungry[up-hungry]').text('old hungry')
|
56
78
|
affix('.target').text('old target')
|
@@ -4,6 +4,102 @@ describe 'up.util', ->
|
|
4
4
|
|
5
5
|
describe 'JavaScript functions', ->
|
6
6
|
|
7
|
+
describe 'up.util.uniq', ->
|
8
|
+
|
9
|
+
it 'returns the given array with duplicates elements removed', ->
|
10
|
+
input = [1, 2, 1, 1, 3]
|
11
|
+
result = up.util.uniq(input)
|
12
|
+
expect(result).toEqual [1, 2, 3]
|
13
|
+
|
14
|
+
it 'works on DOM elements', ->
|
15
|
+
one = document.createElement("div")
|
16
|
+
two = document.createElement("div")
|
17
|
+
input = [one, one, two, two]
|
18
|
+
result = up.util.uniq(input)
|
19
|
+
expect(result).toEqual [one, two]
|
20
|
+
|
21
|
+
it 'preserves insertion order', ->
|
22
|
+
input = [1, 2, 1]
|
23
|
+
result = up.util.uniq(input)
|
24
|
+
expect(result).toEqual [1, 2]
|
25
|
+
|
26
|
+
describe 'up.util.uniqBy', ->
|
27
|
+
|
28
|
+
it 'returns the given array with duplicate elements removed, calling the given function to determine value for uniqueness', ->
|
29
|
+
input = ["foo", "bar", "apple", 'orange', 'banana']
|
30
|
+
result = up.util.uniqBy(input, (element) -> element.length)
|
31
|
+
expect(result).toEqual ['foo', 'apple', 'orange']
|
32
|
+
|
33
|
+
it 'accepts a property name instead of a function, which collects that property from each item to compute uniquness', ->
|
34
|
+
input = ["foo", "bar", "apple", 'orange', 'banana']
|
35
|
+
result = up.util.uniqBy(input, 'length')
|
36
|
+
expect(result).toEqual ['foo', 'apple', 'orange']
|
37
|
+
|
38
|
+
describe 'up.util.map', ->
|
39
|
+
|
40
|
+
it 'creates a new array of values by calling the given function on each item of the given array', ->
|
41
|
+
array = ["apple", "orange", "cucumber"]
|
42
|
+
mapped = up.util.map(array, (element) -> element.length)
|
43
|
+
expect(mapped).toEqual [5, 6, 8]
|
44
|
+
|
45
|
+
it 'accepts a property name instead of a function, which collects that property from each item', ->
|
46
|
+
array = ["apple", "orange", "cucumber"]
|
47
|
+
mapped = up.util.map(array, 'length')
|
48
|
+
expect(mapped).toEqual [5, 6, 8]
|
49
|
+
|
50
|
+
it 'passes the iteration index as second argument to the given function', ->
|
51
|
+
array = ["apple", "orange", "cucumber"]
|
52
|
+
mapped = up.util.map(array, (element, i) -> i)
|
53
|
+
expect(mapped).toEqual [0, 1, 2]
|
54
|
+
|
55
|
+
describe 'up.util.each', ->
|
56
|
+
|
57
|
+
it 'calls the given function once for each itm of the given array', ->
|
58
|
+
args = []
|
59
|
+
array = ["apple", "orange", "cucumber"]
|
60
|
+
up.util.each array, (item) -> args.push(item)
|
61
|
+
expect(args).toEqual ["apple", "orange", "cucumber"]
|
62
|
+
|
63
|
+
it 'passes the iteration index as second argument to the given function', ->
|
64
|
+
args = []
|
65
|
+
array = ["apple", "orange", "cucumber"]
|
66
|
+
up.util.each array, (item, index) -> args.push(index)
|
67
|
+
expect(args).toEqual [0, 1, 2]
|
68
|
+
|
69
|
+
describe 'up.util.select', ->
|
70
|
+
|
71
|
+
it 'returns an array of those elements in the given array for which the given function returns true', ->
|
72
|
+
array = ["foo", "orange", "cucumber"]
|
73
|
+
results = up.util.select array, (item) -> item.length > 3
|
74
|
+
expect(results).toEqual ['orange', 'cucumber']
|
75
|
+
|
76
|
+
it 'passes the iteration index as second argument to the given function', ->
|
77
|
+
array = ["apple", "orange", "cucumber", "banana"]
|
78
|
+
results = up.util.select array, (item, index) -> index % 2 == 0
|
79
|
+
expect(results).toEqual ['apple', 'cucumber']
|
80
|
+
|
81
|
+
it 'accepts a property name instead of a function, which checks that property from each item', ->
|
82
|
+
array = [ { name: 'a', prop: false }, { name: 'b', prop: true } ]
|
83
|
+
results = up.util.select array, 'prop'
|
84
|
+
expect(results).toEqual [{ name: 'b', prop: true }]
|
85
|
+
|
86
|
+
describe 'up.util.reject', ->
|
87
|
+
|
88
|
+
it 'returns an array of those elements in the given array for which the given function returns false', ->
|
89
|
+
array = ["foo", "orange", "cucumber"]
|
90
|
+
results = up.util.reject array, (item) -> item.length < 4
|
91
|
+
expect(results).toEqual ['orange', 'cucumber']
|
92
|
+
|
93
|
+
it 'passes the iteration index as second argument to the given function', ->
|
94
|
+
array = ["apple", "orange", "cucumber", "banana"]
|
95
|
+
results = up.util.reject array, (item, index) -> index % 2 == 0
|
96
|
+
expect(results).toEqual ['orange', 'banana']
|
97
|
+
|
98
|
+
it 'accepts a property name instead of a function, which checks that property from each item', ->
|
99
|
+
array = [ { name: 'a', prop: false }, { name: 'b', prop: true } ]
|
100
|
+
results = up.util.reject array, 'prop'
|
101
|
+
expect(results).toEqual [{ name: 'a', prop: false }]
|
102
|
+
|
7
103
|
describe 'up.util.previewable', ->
|
8
104
|
|
9
105
|
it 'wraps a function into a proxy function with an additional .promise attribute', ->
|
@@ -378,6 +474,75 @@ describe 'up.util', ->
|
|
378
474
|
up.util.isPresent(element)
|
379
475
|
expect(count).toBe(3)
|
380
476
|
|
477
|
+
it 'passes the iteration index as second argument to the given function', ->
|
478
|
+
array = ["apple", "orange", "cucumber"]
|
479
|
+
args = []
|
480
|
+
up.util.all array, (item, index) ->
|
481
|
+
args.push(index)
|
482
|
+
true
|
483
|
+
expect(args).toEqual [0, 1, 2]
|
484
|
+
|
485
|
+
it 'accepts a property name instead of a function, which collects that property from each item', ->
|
486
|
+
allTrue = [ { prop: true }, { prop: true } ]
|
487
|
+
someFalse = [ { prop: true }, { prop: false } ]
|
488
|
+
expect(up.util.all(allTrue, 'prop')).toBe(true)
|
489
|
+
expect(up.util.all(someFalse, 'prop')).toBe(false)
|
490
|
+
|
491
|
+
# describe 'up.util.none', ->
|
492
|
+
#
|
493
|
+
# it 'returns true if no element in the array returns true for the given function', ->
|
494
|
+
# result = up.util.none ['foo', 'bar', 'baz'], up.util.isBlank
|
495
|
+
# expect(result).toBe(true)
|
496
|
+
#
|
497
|
+
# it 'returns false if an element in the array returns false for the given function', ->
|
498
|
+
# result = up.util.none ['foo', 'bar', null, 'baz'], up.util.isBlank
|
499
|
+
# expect(result).toBe(false)
|
500
|
+
#
|
501
|
+
# it 'short-circuits once an element returns true', ->
|
502
|
+
# count = 0
|
503
|
+
# up.util.none ['foo', 'bar', '', 'baz'], (element) ->
|
504
|
+
# count += 1
|
505
|
+
# up.util.isBlank(element)
|
506
|
+
# expect(count).toBe(3)
|
507
|
+
#
|
508
|
+
# it 'passes the iteration index as second argument to the given function', ->
|
509
|
+
# array = ["apple", "orange", "cucumber"]
|
510
|
+
# args = []
|
511
|
+
# up.util.none array, (item, index) ->
|
512
|
+
# args.push(index)
|
513
|
+
# false
|
514
|
+
# expect(args).toEqual [0, 1, 2]
|
515
|
+
#
|
516
|
+
# it 'accepts a property name instead of a function, which collects that property from each item', ->
|
517
|
+
# allFalse = [ { prop: false }, { prop: false } ]
|
518
|
+
# someTrue = [ { prop: true }, { prop: false } ]
|
519
|
+
# expect(up.util.none(allFalse, 'prop')).toBe(true)
|
520
|
+
# expect(up.util.none(someTrue, 'prop')).toBe(false)
|
521
|
+
|
522
|
+
describe 'up.util.any', ->
|
523
|
+
|
524
|
+
it 'returns true if at least one element in the array returns true for the given function', ->
|
525
|
+
result = up.util.any ['', 'bar', null], up.util.isPresent
|
526
|
+
expect(result).toBe(true)
|
527
|
+
|
528
|
+
it 'returns false if no element in the array returns true for the given function', ->
|
529
|
+
result = up.util.any ['', null, undefined], up.util.isPresent
|
530
|
+
expect(result).toBe(false)
|
531
|
+
|
532
|
+
it 'passes the iteration index as second argument to the given function', ->
|
533
|
+
array = ["apple", "orange", "cucumber"]
|
534
|
+
args = []
|
535
|
+
up.util.any array, (item, index) ->
|
536
|
+
args.push(index)
|
537
|
+
false
|
538
|
+
expect(args).toEqual [0, 1, 2]
|
539
|
+
|
540
|
+
it 'accepts a property name instead of a function, which collects that property from each item', ->
|
541
|
+
someTrue = [ { prop: true }, { prop: false } ]
|
542
|
+
allFalse = [ { prop: false }, { prop: false } ]
|
543
|
+
expect(up.util.any(someTrue, 'prop')).toBe(true)
|
544
|
+
expect(up.util.any(allFalse, 'prop')).toBe(false)
|
545
|
+
|
381
546
|
describe 'up.util.isBlank', ->
|
382
547
|
|
383
548
|
it 'returns false for false', ->
|
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.
|
4
|
+
version: 0.55.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- lib/assets/javascripts/unpoly/classes/cache.coffee
|
100
100
|
- lib/assets/javascripts/unpoly/classes/extract_cascade.coffee
|
101
101
|
- lib/assets/javascripts/unpoly/classes/extract_plan.coffee
|
102
|
+
- lib/assets/javascripts/unpoly/classes/extract_step.coffee
|
102
103
|
- lib/assets/javascripts/unpoly/classes/field_observer.coffee
|
103
104
|
- lib/assets/javascripts/unpoly/classes/follow_variant.coffee
|
104
105
|
- lib/assets/javascripts/unpoly/classes/motion_tracker.coffee
|
@@ -271,6 +272,7 @@ files:
|
|
271
272
|
- spec_app/spec/javascripts/helpers/to_equal_jquery.js.coffee
|
272
273
|
- spec_app/spec/javascripts/helpers/to_have_request_method.js.coffee
|
273
274
|
- spec_app/spec/javascripts/helpers/to_have_unhandled_rejections.coffee
|
275
|
+
- spec_app/spec/javascripts/helpers/to_match_text.js.coffee
|
274
276
|
- spec_app/spec/javascripts/helpers/to_match_url.coffee
|
275
277
|
- spec_app/spec/javascripts/helpers/trigger.js.coffee
|
276
278
|
- spec_app/spec/javascripts/helpers/wait_until_dom_ready.js.coffee
|