@lightningjs/blits 1.23.2 → 1.24.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.
- package/.github/workflows/run-blits-tests.yml +3 -0
- package/CHANGELOG.md +9 -0
- package/package.json +1 -1
- package/src/components/FPScounter.js +2 -2
- package/src/engines/L3/element.js +3 -4
- package/src/lib/codegenerator/generator.js +2 -2
- package/src/lib/codegenerator/generator.test.js +206 -3
- package/src/router/router.js +3 -1
- package/src/router/router.test.js +244 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.24.0
|
|
4
|
+
|
|
5
|
+
_26 mar 2025_
|
|
6
|
+
|
|
7
|
+
- Added additional tests for router
|
|
8
|
+
- Fixed issues with `:show` attribute not working properly
|
|
9
|
+
- Fixed issue with strings starting with a number being casted to a number
|
|
10
|
+
- Fixed named slots functionality
|
|
11
|
+
|
|
3
12
|
## v1.23.2
|
|
4
13
|
|
|
5
14
|
_18 mar 2025_
|
package/package.json
CHANGED
|
@@ -736,7 +736,7 @@ export default () =>
|
|
|
736
736
|
)
|
|
737
737
|
|
|
738
738
|
elementConfig23['image'] = component.image
|
|
739
|
-
elementConfig23['x'] = -2
|
|
739
|
+
elementConfig23['x'] = '-2'
|
|
740
740
|
elementConfig23['w'] = 47
|
|
741
741
|
elementConfig23['h'] = 25
|
|
742
742
|
elementConfig23['map'] = component.sprite
|
|
@@ -759,7 +759,7 @@ export default () =>
|
|
|
759
759
|
parent = elms[23]
|
|
760
760
|
const props24 = {}
|
|
761
761
|
props24['image'] = component.image
|
|
762
|
-
props24['x'] = -2
|
|
762
|
+
props24['x'] = '-2'
|
|
763
763
|
props24['w'] = 47
|
|
764
764
|
props24['h'] = 25
|
|
765
765
|
props24['map'] = component.sprite
|
|
@@ -82,6 +82,9 @@ const layoutFn = function (config) {
|
|
|
82
82
|
let otherDimension = 0
|
|
83
83
|
const gap = config.gap || 0
|
|
84
84
|
for (let i = 0; i < childrenLength; i++) {
|
|
85
|
+
if (this.children[i] !== undefined && this.children[i].props.raw.show === false) {
|
|
86
|
+
continue
|
|
87
|
+
}
|
|
85
88
|
const node = children[i]
|
|
86
89
|
node[position] = offset
|
|
87
90
|
node[oppositePosition] = padding.oppositeStart
|
|
@@ -303,12 +306,8 @@ const propsTransformer = {
|
|
|
303
306
|
set show(v) {
|
|
304
307
|
if (v) {
|
|
305
308
|
this.props['alpha'] = this.raw['alpha'] !== undefined ? this.raw['alpha'] : 1
|
|
306
|
-
this.props['width'] = this.raw['w'] || this.raw['width'] || 0
|
|
307
|
-
this.props['height'] = this.raw['h'] || this.raw['height'] || 0
|
|
308
309
|
} else {
|
|
309
310
|
this.props['alpha'] = 0
|
|
310
|
-
this.props['width'] = 0
|
|
311
|
-
this.props['height'] = 0
|
|
312
311
|
}
|
|
313
312
|
},
|
|
314
313
|
set alpha(v) {
|
|
@@ -148,7 +148,7 @@ const generateElementCode = function (
|
|
|
148
148
|
Object.keys(templateObject).forEach((key) => {
|
|
149
149
|
if (key === 'slot') {
|
|
150
150
|
renderCode.push(`
|
|
151
|
-
elementConfig${counter}['parent'] =
|
|
151
|
+
elementConfig${counter}['parent'] = slotComponent[Symbol.for('slots')] !== undefined && Array.isArray(slotComponent[Symbol.for('slots')]) === true && slotComponent[Symbol.for('slots')].filter(slot => slot.ref === '${templateObject.slot}').shift() || parent
|
|
152
152
|
`)
|
|
153
153
|
}
|
|
154
154
|
|
|
@@ -691,7 +691,7 @@ const cast = (val = '', key = false, component = 'component.') => {
|
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
693
|
// numeric
|
|
694
|
-
else if (key !== 'color' && !isNaN(parseFloat(val))) {
|
|
694
|
+
else if (key !== 'color' && /[^0-9%\s.eE]/.test(val) === false && !isNaN(parseFloat(val))) {
|
|
695
695
|
castedValue = parseFloat(val)
|
|
696
696
|
if (val.endsWith('%')) {
|
|
697
697
|
const map = {
|
|
@@ -296,6 +296,71 @@ test('Generate code for a template with a single element with attributes with a
|
|
|
296
296
|
assert.end()
|
|
297
297
|
})
|
|
298
298
|
|
|
299
|
+
test('Generate code for a template with a single element with attributes with numeric & alpha numeric value', (assert) => {
|
|
300
|
+
const templateObject = {
|
|
301
|
+
children: [
|
|
302
|
+
{
|
|
303
|
+
[Symbol.for('componentType')]: 'Element',
|
|
304
|
+
x: '10e2',
|
|
305
|
+
y: '100',
|
|
306
|
+
h: '45%',
|
|
307
|
+
w: '45.45%',
|
|
308
|
+
one: 'Pure String',
|
|
309
|
+
two: '123abc',
|
|
310
|
+
three: '1E',
|
|
311
|
+
four: 'E1',
|
|
312
|
+
},
|
|
313
|
+
],
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const expectedRender = `
|
|
317
|
+
function anonymous(parent, component, context, components, effect, getRaw, Log) {
|
|
318
|
+
const elms = []
|
|
319
|
+
let componentType
|
|
320
|
+
const rootComponent = component
|
|
321
|
+
let propData
|
|
322
|
+
let slotComponent
|
|
323
|
+
let inSlot = false
|
|
324
|
+
let slotChildCounter = 0
|
|
325
|
+
const elementConfig0 = {}
|
|
326
|
+
|
|
327
|
+
elms[0] = this.element(
|
|
328
|
+
{ parent: parent || 'root' },
|
|
329
|
+
inSlot === true ? slotComponent : component
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
elementConfig0['x'] = 1000
|
|
333
|
+
elementConfig0['y'] = 100
|
|
334
|
+
elementConfig0['h'] = parent.node.height * (45 / 100)
|
|
335
|
+
elementConfig0['w'] = parent.node.width * (45.45 / 100)
|
|
336
|
+
elementConfig0['one'] = "Pure String"
|
|
337
|
+
elementConfig0['two'] = "123abc"
|
|
338
|
+
elementConfig0['three'] = 1
|
|
339
|
+
elementConfig0['four'] = "E1"
|
|
340
|
+
|
|
341
|
+
elms[0].populate(elementConfig0)
|
|
342
|
+
|
|
343
|
+
if (inSlot === true) {
|
|
344
|
+
slotChildCounter -= 1
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return elms
|
|
348
|
+
}
|
|
349
|
+
`
|
|
350
|
+
|
|
351
|
+
const actual = generator.call(scope, templateObject)
|
|
352
|
+
assert.equal(
|
|
353
|
+
normalize(actual.render.toString()),
|
|
354
|
+
normalize(expectedRender),
|
|
355
|
+
'Generator should return a render function with the correct code'
|
|
356
|
+
)
|
|
357
|
+
assert.ok(
|
|
358
|
+
Array.isArray(actual.effects) && actual.effects.length === 0,
|
|
359
|
+
'Generator should return an empty effects array'
|
|
360
|
+
)
|
|
361
|
+
assert.end()
|
|
362
|
+
})
|
|
363
|
+
|
|
299
364
|
test('Generate code for a template with attributes and a nested element with attributes', (assert) => {
|
|
300
365
|
const templateObject = {
|
|
301
366
|
children: [
|
|
@@ -1427,6 +1492,144 @@ test('Generate code for a template with custom components with arguments', (asse
|
|
|
1427
1492
|
assert.end()
|
|
1428
1493
|
})
|
|
1429
1494
|
|
|
1495
|
+
test('Generate code for a template with custom components with argument value as numeric & alpha numeric', (assert) => {
|
|
1496
|
+
const templateObject = {
|
|
1497
|
+
children: [
|
|
1498
|
+
{
|
|
1499
|
+
[Symbol.for('componentType')]: 'Element',
|
|
1500
|
+
children: [
|
|
1501
|
+
{
|
|
1502
|
+
[Symbol.for('componentType')]: 'Poster',
|
|
1503
|
+
x: '10e2',
|
|
1504
|
+
y: '100',
|
|
1505
|
+
h: '45%',
|
|
1506
|
+
w: '45.45%',
|
|
1507
|
+
one: 'Pure String',
|
|
1508
|
+
two: '123abc',
|
|
1509
|
+
three: '1E',
|
|
1510
|
+
four: 'E1',
|
|
1511
|
+
},
|
|
1512
|
+
],
|
|
1513
|
+
},
|
|
1514
|
+
],
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
const scope = {
|
|
1518
|
+
components: {
|
|
1519
|
+
Poster: () => {},
|
|
1520
|
+
},
|
|
1521
|
+
}
|
|
1522
|
+
|
|
1523
|
+
const expectedRender = `
|
|
1524
|
+
function anonymous(parent, component, context, components, effect, getRaw, Log) {
|
|
1525
|
+
const elms = []
|
|
1526
|
+
let componentType
|
|
1527
|
+
const rootComponent = component
|
|
1528
|
+
let propData
|
|
1529
|
+
let slotComponent
|
|
1530
|
+
let inSlot = false
|
|
1531
|
+
let slotChildCounter = 0
|
|
1532
|
+
const elementConfig0 = {}
|
|
1533
|
+
|
|
1534
|
+
elms[0] = this.element(
|
|
1535
|
+
{ parent: parent || 'root' },
|
|
1536
|
+
inSlot === true ? slotComponent : component
|
|
1537
|
+
)
|
|
1538
|
+
elms[0].populate(elementConfig0)
|
|
1539
|
+
|
|
1540
|
+
if (inSlot === true) {
|
|
1541
|
+
slotChildCounter -= 1
|
|
1542
|
+
}
|
|
1543
|
+
|
|
1544
|
+
const cmp1 = (context.components && context.components['Poster']) || components['Poster']
|
|
1545
|
+
parent = elms[0]
|
|
1546
|
+
const elementConfig1 = {}
|
|
1547
|
+
|
|
1548
|
+
elms[1] = this.element(
|
|
1549
|
+
{ parent: parent || 'root' },
|
|
1550
|
+
inSlot === true ? slotComponent : component
|
|
1551
|
+
)
|
|
1552
|
+
|
|
1553
|
+
elementConfig1['x'] = 1000
|
|
1554
|
+
elementConfig1['y'] = 100
|
|
1555
|
+
elementConfig1['h'] = parent.node.height * (45 / 100)
|
|
1556
|
+
elementConfig1['w'] = parent.node.width * (45.45 / 100)
|
|
1557
|
+
elementConfig1['one'] = "PureString"
|
|
1558
|
+
elementConfig1['two'] = "123abc"
|
|
1559
|
+
elementConfig1['three'] = 1
|
|
1560
|
+
elementConfig1['four'] = "E1"
|
|
1561
|
+
|
|
1562
|
+
const skip1 = []
|
|
1563
|
+
if (typeof cmp1 !== 'undefined') {
|
|
1564
|
+
for (let key in cmp1.config.props) {
|
|
1565
|
+
delete elementConfig1[cmp1.config.props[key]]
|
|
1566
|
+
skip1.push(cmp1.config.props[key])
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
elms[1].populate(elementConfig1)
|
|
1571
|
+
|
|
1572
|
+
if (inSlot === true) {
|
|
1573
|
+
slotChildCounter -= 1
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
parent = elms[1]
|
|
1577
|
+
const props2 = {}
|
|
1578
|
+
|
|
1579
|
+
props2['x'] = 1000
|
|
1580
|
+
props2['y'] = 100
|
|
1581
|
+
props2['h'] = parent.node.height * (45 / 100)
|
|
1582
|
+
props2['w'] = parent.node.width * (45.45 / 100)
|
|
1583
|
+
props2['one'] = "PureString"
|
|
1584
|
+
props2['two'] = "123abc"
|
|
1585
|
+
props2['three'] = 1
|
|
1586
|
+
props2['four'] = "E1"
|
|
1587
|
+
|
|
1588
|
+
componentType = props2['is'] || 'Poster'
|
|
1589
|
+
let component2
|
|
1590
|
+
|
|
1591
|
+
if (typeof componentType === 'string') {
|
|
1592
|
+
component2 = context.components && context.components[componentType] || components[componentType]
|
|
1593
|
+
if (!component2) {
|
|
1594
|
+
throw new Error('Component "Poster" not found')
|
|
1595
|
+
}
|
|
1596
|
+
} else if (typeof componentType === 'function' && componentType[Symbol.for('isComponent')] === true) {
|
|
1597
|
+
component2 = componentType
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
elms[2] = component2.call(null, { props: props2 }, elms[1], component)
|
|
1601
|
+
|
|
1602
|
+
if (elms[2][Symbol.for('slots')][0]) {
|
|
1603
|
+
parent = elms[2][Symbol.for('slots')][0]
|
|
1604
|
+
slotComponent = elms[2]
|
|
1605
|
+
inSlot = true
|
|
1606
|
+
} else {
|
|
1607
|
+
parent = elms[2][Symbol.for('children')][0]
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
if (inSlot === true && slotChildCounter === 0) {
|
|
1611
|
+
inSlot = false
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
return elms
|
|
1615
|
+
}
|
|
1616
|
+
`
|
|
1617
|
+
|
|
1618
|
+
const actual = generator.call(scope, templateObject)
|
|
1619
|
+
|
|
1620
|
+
assert.equal(
|
|
1621
|
+
normalize(actual.render.toString()),
|
|
1622
|
+
normalize(expectedRender),
|
|
1623
|
+
'Generator should return a render function with the correct code'
|
|
1624
|
+
)
|
|
1625
|
+
assert.ok(
|
|
1626
|
+
Array.isArray(actual.effects) && actual.effects.length === 0,
|
|
1627
|
+
'Generator should return an empty effects array'
|
|
1628
|
+
)
|
|
1629
|
+
|
|
1630
|
+
assert.end()
|
|
1631
|
+
})
|
|
1632
|
+
|
|
1430
1633
|
test('Generate code for a template with custom components with reactive props', (assert) => {
|
|
1431
1634
|
const templateObject = {
|
|
1432
1635
|
children: [
|
|
@@ -1933,9 +2136,9 @@ test('Generate code for a template with slot content, using a named slot', (asse
|
|
|
1933
2136
|
elms[4] = this.element({ parent: parent || 'root' }, inSlot === true ? slotComponent : component)
|
|
1934
2137
|
elementConfig4['x'] = 100
|
|
1935
2138
|
elementConfig4['y'] = component.y
|
|
1936
|
-
elementConfig4['parent'] =
|
|
1937
|
-
Array.isArray(
|
|
1938
|
-
|
|
2139
|
+
elementConfig4['parent'] = slotComponent[Symbol.for('slots')] !== undefined &&
|
|
2140
|
+
Array.isArray(slotComponent[Symbol.for('slots')]) === true &&
|
|
2141
|
+
slotComponent[Symbol.for('slots')].filter(slot => slot.ref === 'mySlot').shift() || parent
|
|
1939
2142
|
elementConfig4['slot'] = "mySlot"
|
|
1940
2143
|
elms[4].populate(elementConfig4)
|
|
1941
2144
|
|
package/src/router/router.js
CHANGED
|
@@ -66,7 +66,7 @@ const isString = (v) => typeof v === 'string'
|
|
|
66
66
|
|
|
67
67
|
export const matchHash = (path, routes = []) => {
|
|
68
68
|
// remove trailing slashes
|
|
69
|
-
const originalPath = path
|
|
69
|
+
const originalPath = path.replace(/^\/+|\/+$/g, '')
|
|
70
70
|
path = normalizePath(path)
|
|
71
71
|
let matchingRoute = false
|
|
72
72
|
let i = 0
|
|
@@ -89,6 +89,8 @@ export const matchHash = (path, routes = []) => {
|
|
|
89
89
|
dynamicRoutePartsRegex.substring(part.index + part[0].length)
|
|
90
90
|
})
|
|
91
91
|
|
|
92
|
+
dynamicRoutePartsRegex = '^' + dynamicRoutePartsRegex
|
|
93
|
+
|
|
92
94
|
// test if the constructed regex matches the path
|
|
93
95
|
const match = originalPath.match(new RegExp(`${dynamicRoutePartsRegex}`, 'i'))
|
|
94
96
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import test from 'tape'
|
|
19
|
-
import { matchHash } from './router.js'
|
|
19
|
+
import { matchHash, getHash, to } from './router.js'
|
|
20
20
|
|
|
21
21
|
const routes = [
|
|
22
22
|
{
|
|
@@ -31,6 +31,9 @@ const routes = [
|
|
|
31
31
|
{
|
|
32
32
|
path: '/tv/:show/seasons/:season',
|
|
33
33
|
},
|
|
34
|
+
{
|
|
35
|
+
path: '/movies/special',
|
|
36
|
+
},
|
|
34
37
|
{
|
|
35
38
|
path: '/movies/:name',
|
|
36
39
|
},
|
|
@@ -40,6 +43,9 @@ const routes = [
|
|
|
40
43
|
{
|
|
41
44
|
path: '/route/with/trailing/slash/',
|
|
42
45
|
},
|
|
46
|
+
{
|
|
47
|
+
path: '/dutchmovies/:id',
|
|
48
|
+
},
|
|
43
49
|
{
|
|
44
50
|
path: '*',
|
|
45
51
|
},
|
|
@@ -54,6 +60,7 @@ test('Type of matchHash', (assert) => {
|
|
|
54
60
|
})
|
|
55
61
|
|
|
56
62
|
test('Match paths with static routes that have an exact match', (assert) => {
|
|
63
|
+
assert.equal(matchHash('', routes), routes[0], 'Should return the correct route object')
|
|
57
64
|
assert.equal(matchHash('/', routes), routes[0], 'Should return the correct route object')
|
|
58
65
|
assert.equal(matchHash('/page1', routes), routes[1], 'Should return the correct route object')
|
|
59
66
|
assert.equal(
|
|
@@ -61,6 +68,11 @@ test('Match paths with static routes that have an exact match', (assert) => {
|
|
|
61
68
|
routes[2],
|
|
62
69
|
'Should return the correct route object'
|
|
63
70
|
)
|
|
71
|
+
assert.equal(
|
|
72
|
+
matchHash('/movies/special', routes),
|
|
73
|
+
routes[4],
|
|
74
|
+
'Should return the correct route object'
|
|
75
|
+
)
|
|
64
76
|
assert.end()
|
|
65
77
|
})
|
|
66
78
|
|
|
@@ -71,32 +83,69 @@ test('Match paths with dynamic route parts', (assert) => {
|
|
|
71
83
|
'Should return the correct route object'
|
|
72
84
|
)
|
|
73
85
|
|
|
86
|
+
assert.equal(
|
|
87
|
+
matchHash('/tv/simpsons/season/first', routes),
|
|
88
|
+
routes[9],
|
|
89
|
+
'Should return the correct route object'
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert.equal(
|
|
93
|
+
matchHash('/examples/test/seasons/5', routes),
|
|
94
|
+
routes[6],
|
|
95
|
+
'Should return the correct route object'
|
|
96
|
+
)
|
|
97
|
+
|
|
74
98
|
assert.equal(
|
|
75
99
|
matchHash('/movies/avengers-endgame', routes),
|
|
76
|
-
routes[
|
|
100
|
+
routes[5],
|
|
77
101
|
'Should return the correct route object'
|
|
78
102
|
)
|
|
103
|
+
|
|
104
|
+
assert.equal(
|
|
105
|
+
matchHash('/movies/special-1', routes),
|
|
106
|
+
routes[5],
|
|
107
|
+
'Should return the correct route object'
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
assert.equal(
|
|
111
|
+
matchHash('/dutchmovies/123', routes),
|
|
112
|
+
routes[8],
|
|
113
|
+
'Should return the correct route object'
|
|
114
|
+
)
|
|
115
|
+
|
|
79
116
|
assert.end()
|
|
80
117
|
})
|
|
81
118
|
|
|
82
119
|
test('Match paths with a wildcard asterix', (assert) => {
|
|
83
120
|
assert.equal(
|
|
84
121
|
matchHash('/examples/example1', routes),
|
|
85
|
-
routes[
|
|
122
|
+
routes[6],
|
|
86
123
|
'Should return the correct route object'
|
|
87
124
|
)
|
|
88
125
|
|
|
89
126
|
assert.equal(
|
|
90
127
|
matchHash('/examples/example1/subexample/and-another-page', routes),
|
|
91
|
-
routes[
|
|
128
|
+
routes[6],
|
|
92
129
|
'Should return the correct route object'
|
|
93
130
|
)
|
|
94
131
|
|
|
95
|
-
assert.equal(matchHash('/404', routes), routes[
|
|
132
|
+
assert.equal(matchHash('/404', routes), routes[9], 'Should return the correct route object')
|
|
133
|
+
|
|
134
|
+
assert.equal(
|
|
135
|
+
matchHash('/page1/non-existing-path', routes),
|
|
136
|
+
routes[9],
|
|
137
|
+
'Should return the correct route object'
|
|
138
|
+
)
|
|
96
139
|
|
|
97
140
|
assert.equal(
|
|
98
141
|
matchHash('/page1/subpage1/i-dont-exist', routes),
|
|
99
|
-
routes[
|
|
142
|
+
routes[9],
|
|
143
|
+
'Should return the correct route object'
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
assert.equal(
|
|
147
|
+
matchHash('/completely/unexpected/route', routes),
|
|
148
|
+
routes[9],
|
|
100
149
|
'Should return the correct route object'
|
|
101
150
|
)
|
|
102
151
|
|
|
@@ -124,6 +173,15 @@ test('Add params to route for dynamic route matches', (assert) => {
|
|
|
124
173
|
'Should return the correct route object'
|
|
125
174
|
)
|
|
126
175
|
|
|
176
|
+
const match3 = matchHash('/dutchmovies/1', routes)
|
|
177
|
+
assert.deepEqual(
|
|
178
|
+
match3.params,
|
|
179
|
+
{
|
|
180
|
+
id: '1',
|
|
181
|
+
},
|
|
182
|
+
'Should return the correct route object'
|
|
183
|
+
)
|
|
184
|
+
|
|
127
185
|
assert.end()
|
|
128
186
|
})
|
|
129
187
|
|
|
@@ -166,7 +224,13 @@ test('Work with trailing slashes', (assert) => {
|
|
|
166
224
|
|
|
167
225
|
assert.equal(
|
|
168
226
|
matchHash('/route/with/trailing/slash', routes),
|
|
169
|
-
routes[
|
|
227
|
+
routes[7],
|
|
228
|
+
'Should return the correct route object'
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
assert.equal(
|
|
232
|
+
matchHash('/tv/simpsons/seasons/first', routes),
|
|
233
|
+
routes[3],
|
|
170
234
|
'Should return the correct route object'
|
|
171
235
|
)
|
|
172
236
|
|
|
@@ -185,7 +249,13 @@ test('Work with and without leading slashes', (assert) => {
|
|
|
185
249
|
|
|
186
250
|
assert.equal(
|
|
187
251
|
matchHash('route/with/trailing/slash', routes),
|
|
188
|
-
routes[
|
|
252
|
+
routes[7],
|
|
253
|
+
'Should return the correct route object'
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
assert.equal(
|
|
257
|
+
matchHash('//tv/simpsons/seasons/first//', routes),
|
|
258
|
+
routes[3],
|
|
189
259
|
'Should return the correct route object'
|
|
190
260
|
)
|
|
191
261
|
|
|
@@ -208,7 +278,7 @@ test('Match routes case insensitive', (assert) => {
|
|
|
208
278
|
|
|
209
279
|
assert.equal(
|
|
210
280
|
matchHash('/Movies/Avengers-Endgame', routes),
|
|
211
|
-
routes[
|
|
281
|
+
routes[5],
|
|
212
282
|
'Should return the correct route object'
|
|
213
283
|
)
|
|
214
284
|
assert.end()
|
|
@@ -234,5 +304,170 @@ test('Match routes case insensitive, but pass props with original casing', (asse
|
|
|
234
304
|
'Should return the correct params object'
|
|
235
305
|
)
|
|
236
306
|
|
|
307
|
+
const match3 = matchHash('/DutchMovies/ID_123', routes)
|
|
308
|
+
assert.deepEqual(
|
|
309
|
+
match3.params,
|
|
310
|
+
{
|
|
311
|
+
id: 'ID_123',
|
|
312
|
+
},
|
|
313
|
+
'Should return the correct params object'
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
assert.end()
|
|
317
|
+
})
|
|
318
|
+
|
|
319
|
+
test('Match paths with dynamic route parts along with query string params', (assert) => {
|
|
320
|
+
const hash1 = '#/tv/simpsons/seasons/first?token=123&ln=en'
|
|
321
|
+
document.location.hash = hash1
|
|
322
|
+
|
|
323
|
+
const { hash, path, queryParams } = getHash()
|
|
324
|
+
|
|
325
|
+
assert.equal(hash, hash1, 'Should return correct hash')
|
|
326
|
+
assert.equal(path, '/tv/simpsons/seasons/first', 'Should return the correct route path')
|
|
327
|
+
assert.equal(matchHash(path, routes), routes[3], 'Should return the correct route object')
|
|
328
|
+
assert.equal(
|
|
329
|
+
queryParams.get('token'),
|
|
330
|
+
'123',
|
|
331
|
+
'Should contain the correct query parameter key with value'
|
|
332
|
+
)
|
|
333
|
+
assert.equal(
|
|
334
|
+
queryParams.get('ln'),
|
|
335
|
+
'en',
|
|
336
|
+
'Should contain the correct query parameter key with value'
|
|
337
|
+
)
|
|
338
|
+
assert.end()
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
test('Get the hash from the URL', (assert) => {
|
|
342
|
+
const hash = '#/movies/action/the-avengers'
|
|
343
|
+
document.location.hash = hash
|
|
344
|
+
|
|
345
|
+
const result = getHash()
|
|
346
|
+
|
|
347
|
+
assert.equal(
|
|
348
|
+
result.hash,
|
|
349
|
+
hash,
|
|
350
|
+
'The result object should contain a hash key with the correct location hash'
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
assert.equal(
|
|
354
|
+
result.path,
|
|
355
|
+
'/movies/action/the-avengers',
|
|
356
|
+
'The result object should contain a path key with the hash (stripped the # symbol)'
|
|
357
|
+
)
|
|
358
|
+
|
|
359
|
+
assert.end()
|
|
360
|
+
})
|
|
361
|
+
|
|
362
|
+
test('Get the hash from the URL and handle query params', (assert) => {
|
|
363
|
+
const hash = '#/movies/comedy/the-hangover?category=1&item=2'
|
|
364
|
+
document.location.hash = hash
|
|
365
|
+
|
|
366
|
+
const result = getHash()
|
|
367
|
+
|
|
368
|
+
assert.equal(
|
|
369
|
+
result.hash,
|
|
370
|
+
hash,
|
|
371
|
+
'The result object should contain a hash key with the correct location hash without the query params'
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
assert.equal(
|
|
375
|
+
result.path,
|
|
376
|
+
'/movies/comedy/the-hangover',
|
|
377
|
+
'The result object should contain a path key with the hash (stripped the # symbol)'
|
|
378
|
+
)
|
|
379
|
+
|
|
380
|
+
assert.equal(
|
|
381
|
+
result.queryParams instanceof URLSearchParams,
|
|
382
|
+
true,
|
|
383
|
+
'The result object should contain a queryParams key with an URLSearchParams object'
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
assert.equal(
|
|
387
|
+
result.queryParams.get('category'),
|
|
388
|
+
'1',
|
|
389
|
+
'The result object should contain a queryParams key with the correct route query param values'
|
|
390
|
+
)
|
|
391
|
+
|
|
392
|
+
assert.equal(
|
|
393
|
+
result.queryParams.get('item'),
|
|
394
|
+
'2',
|
|
395
|
+
'The result object should contain a queryParams key with the correct route query param values'
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
assert.end()
|
|
399
|
+
})
|
|
400
|
+
|
|
401
|
+
test('Get route object from Match hash when navigating using to() method', (assert) => {
|
|
402
|
+
const hash = '/page1/subpage1'
|
|
403
|
+
|
|
404
|
+
to(hash)
|
|
405
|
+
|
|
406
|
+
const result = matchHash(hash, routes)
|
|
407
|
+
|
|
408
|
+
assert.equal(
|
|
409
|
+
result.path,
|
|
410
|
+
'page1/subpage1',
|
|
411
|
+
'The result object should contain a path key with path hash'
|
|
412
|
+
)
|
|
413
|
+
assert.equal(
|
|
414
|
+
Object.keys(result.params).length,
|
|
415
|
+
0,
|
|
416
|
+
'The results object should contain a params key with zero props'
|
|
417
|
+
)
|
|
418
|
+
assert.equal(
|
|
419
|
+
Object.keys(result.data).length,
|
|
420
|
+
0,
|
|
421
|
+
'The results object should contain a data key with zero props'
|
|
422
|
+
)
|
|
423
|
+
assert.equal(
|
|
424
|
+
Object.keys(result.options).length,
|
|
425
|
+
0,
|
|
426
|
+
'The results object should contain a options key with zero props'
|
|
427
|
+
)
|
|
428
|
+
assert.end()
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
test('Get route object from Match hash when navigating using to() method with options', (assert) => {
|
|
432
|
+
const hash = '/page1/subpage1'
|
|
433
|
+
|
|
434
|
+
to(hash, undefined, { keepAlive: true })
|
|
435
|
+
|
|
436
|
+
const result = matchHash(hash, routes)
|
|
437
|
+
|
|
438
|
+
assert.equal(
|
|
439
|
+
result.path,
|
|
440
|
+
'page1/subpage1',
|
|
441
|
+
'The result object should contain a path key with path hash'
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
assert.equal(
|
|
445
|
+
result.options.keepAlive,
|
|
446
|
+
true,
|
|
447
|
+
'The results object should contain a options key with keep alive as True'
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
assert.end()
|
|
451
|
+
})
|
|
452
|
+
|
|
453
|
+
test('Get Hash from URL when navigating using to() method', (assert) => {
|
|
454
|
+
const hash = '#/movies/action/avengers'
|
|
455
|
+
|
|
456
|
+
to(hash)
|
|
457
|
+
|
|
458
|
+
const result = getHash()
|
|
459
|
+
|
|
460
|
+
assert.equal(
|
|
461
|
+
result.hash,
|
|
462
|
+
hash,
|
|
463
|
+
'The result object key property should contain correct location hash'
|
|
464
|
+
)
|
|
465
|
+
|
|
466
|
+
assert.equal(
|
|
467
|
+
result.path,
|
|
468
|
+
'/movies/action/avengers',
|
|
469
|
+
'The result object should contain a path key with hash without #'
|
|
470
|
+
)
|
|
471
|
+
|
|
237
472
|
assert.end()
|
|
238
473
|
})
|