@lightningjs/blits 0.6.11 → 0.6.13
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/CHANGELOG.md +18 -0
- package/bin/helpers.js +1 -1
- package/boilerplate/common/git/gitignore +5 -0
- package/package.json +5 -3
- package/src/component.d.ts +11 -1
- package/src/component.js +2 -4
- package/src/components/FPScounter.js +0 -2
- package/src/components/FPScounter.orig.js +0 -2
- package/src/components/Text.js +5 -1
- package/src/components/Text.orig.js +3 -1
- package/src/element.js +1 -10
- package/src/focus.js +1 -1
- package/src/router/router.js +72 -13
- package/src/router/router.test.js +238 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
# v0.6.13
|
|
4
|
+
|
|
5
|
+
_16 feb 2024_
|
|
6
|
+
|
|
7
|
+
- Upgraded to 0.7.2 of the renderer
|
|
8
|
+
- Introduced new `maxheight` attribute (besided the existing `maxlines` attribute) for the `<Text />` component
|
|
9
|
+
- Fixed issue with order of lifecycle event emits
|
|
10
|
+
- Fixed logic to not unfoces a parent when it passes focus to a child
|
|
11
|
+
- Removed temporary fix for renderer issue [#123](https://github.com/lightning-js/renderer/issues/123)
|
|
12
|
+
|
|
13
|
+
# v0.6.12
|
|
14
|
+
|
|
15
|
+
_9 feb 2024_
|
|
16
|
+
|
|
17
|
+
- Added type hinting for `this.$clearInterval` and `this.$clearTimeout`
|
|
18
|
+
- Fixed issue with `.gitignore` in app create flow
|
|
19
|
+
- Added support for dynamic route parts in the router (i.e `/tv/:series/episodes/:episode`)
|
|
20
|
+
|
|
3
21
|
# v0.6.11
|
|
4
22
|
|
|
5
23
|
_7 feb 2024_
|
package/bin/helpers.js
CHANGED
|
@@ -182,7 +182,7 @@ export const gitInit = (cwd, fixturesBase) => {
|
|
|
182
182
|
.then(({ stdout }) => (msg = stdout))
|
|
183
183
|
.then(() => {
|
|
184
184
|
return fs.copyFileSync(
|
|
185
|
-
path.join(fixturesBase, 'common/git
|
|
185
|
+
path.join(fixturesBase, 'common/git/gitignore'),
|
|
186
186
|
path.join(cwd, '.gitignore')
|
|
187
187
|
)
|
|
188
188
|
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lightningjs/blits",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.13",
|
|
4
4
|
"description": "Blits: The Lightning 3 App Development Framework",
|
|
5
5
|
"bin": "bin/index.js",
|
|
6
6
|
"exports": {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "c8 npm run test:run",
|
|
14
|
-
"test:run": "tape '{,!(node_modules)/**/}*.test.js' | tap-diff",
|
|
14
|
+
"test:run": "node -r 'global-jsdom/register' ./node_modules/.bin/tape '{,!(node_modules)/**/}*.test.js' | tap-diff",
|
|
15
15
|
"lint": "eslint '**/*.js'",
|
|
16
16
|
"lint:fix": "eslint '**/*.js' --fix",
|
|
17
17
|
"prepublishOnly": "node scripts/prepublishOnly.js",
|
|
@@ -36,14 +36,16 @@
|
|
|
36
36
|
"eslint": "^8.8.0",
|
|
37
37
|
"eslint-config-prettier": "^8.3.0",
|
|
38
38
|
"eslint-plugin-prettier": "^4.0.0",
|
|
39
|
+
"global-jsdom": "24.0.0",
|
|
39
40
|
"husky": "^7.0.4",
|
|
41
|
+
"jsdom": "24.0.0",
|
|
40
42
|
"lint-staged": "^12.3.3",
|
|
41
43
|
"prettier": "^2.5.1",
|
|
42
44
|
"tap-diff": "^0.1.1",
|
|
43
45
|
"tape": "^5.5.0"
|
|
44
46
|
},
|
|
45
47
|
"dependencies": {
|
|
46
|
-
"@lightningjs/renderer": "^0.7.
|
|
48
|
+
"@lightningjs/renderer": "^0.7.2",
|
|
47
49
|
"@lightningjs/vite-plugin-import-chunk-url": "^0.3.0",
|
|
48
50
|
"execa": "^8.0.1",
|
|
49
51
|
"kolorist": "^1.8.0",
|
package/src/component.d.ts
CHANGED
|
@@ -142,12 +142,22 @@ declare namespace Component {
|
|
|
142
142
|
* Set a timeout that is automatically cleaned upon component destroy
|
|
143
143
|
*/
|
|
144
144
|
$setTimeout: (callback: (args: any) => void, ms?: number | undefined) => ReturnType<typeof setTimeout>
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Clear a timeout
|
|
148
|
+
*/
|
|
149
|
+
$clearTimeout: (id: ReturnType<typeof setTimeout>) => void
|
|
145
150
|
|
|
146
151
|
/**
|
|
147
152
|
* Set an interval that is automatically cleaned upon component destroy
|
|
148
153
|
*/
|
|
149
154
|
$setInterval: (callback: (args: any) => void, ms?: number | undefined) => ReturnType<typeof setInterval>
|
|
150
|
-
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Clear a interval
|
|
158
|
+
*/
|
|
159
|
+
$clearInterval: (id: ReturnType<typeof setInterval>) => void
|
|
160
|
+
|
|
151
161
|
/**
|
|
152
162
|
* Log to the console with prettier output and configurable debug levels in Settings
|
|
153
163
|
*/
|
package/src/component.js
CHANGED
|
@@ -97,15 +97,13 @@ const Component = (name = required('name'), config = required('config')) => {
|
|
|
97
97
|
},
|
|
98
98
|
set state(v) {
|
|
99
99
|
if (states.indexOf(v) > -1 && v !== this.current) {
|
|
100
|
-
Log.debug(
|
|
101
|
-
`Setting lifecycle state from ${this.previous} to ${v} for ${scope.componentId}`
|
|
102
|
-
)
|
|
100
|
+
Log.debug(`Setting lifecycle state from ${this.current} to ${v} for ${scope.componentId}`)
|
|
103
101
|
this.previous = this.current
|
|
102
|
+
this.current = v
|
|
104
103
|
// emit 'private' hook
|
|
105
104
|
privateEmit(v, name, scope)
|
|
106
105
|
// emit 'public' hook
|
|
107
106
|
emit(v, name, scope)
|
|
108
|
-
this.current = v
|
|
109
107
|
}
|
|
110
108
|
},
|
|
111
109
|
}
|
|
@@ -19,8 +19,6 @@ import Component from '../component.js'
|
|
|
19
19
|
import { renderer } from '../launch.js'
|
|
20
20
|
import fps_sprite from '../../public/assets/fps_sprite.base64.js'
|
|
21
21
|
|
|
22
|
-
console.log(fps_sprite)
|
|
23
|
-
|
|
24
22
|
export default () =>
|
|
25
23
|
Component('FPScounter', {
|
|
26
24
|
/* eslint-disable no-unused-vars */
|
package/src/components/Text.js
CHANGED
|
@@ -67,6 +67,9 @@ export default () =>
|
|
|
67
67
|
function anonymous(component, elms, context) {
|
|
68
68
|
elms[0].set('maxLines', component.maxlines)
|
|
69
69
|
},
|
|
70
|
+
function anonymous(component, elms, context) {
|
|
71
|
+
elms[0].set('h', component.maxheight)
|
|
72
|
+
},
|
|
70
73
|
function anonymous(component, elms, context) {
|
|
71
74
|
elms[0].set('textAlign', component.align)
|
|
72
75
|
},
|
|
@@ -95,6 +98,7 @@ export default () =>
|
|
|
95
98
|
'align',
|
|
96
99
|
'wordwrap',
|
|
97
100
|
'maxlines',
|
|
101
|
+
'maxheight',
|
|
98
102
|
'lineheight',
|
|
99
103
|
'contain',
|
|
100
104
|
'@loaded',
|
|
@@ -105,7 +109,7 @@ export default () =>
|
|
|
105
109
|
_contain() {
|
|
106
110
|
return (
|
|
107
111
|
this.contain ||
|
|
108
|
-
(this.
|
|
112
|
+
(this.maxheight && this.wordwrap ? 'both' : this.wordwrap ? 'width' : 'none')
|
|
109
113
|
)
|
|
110
114
|
},
|
|
111
115
|
_lineheight() {
|
|
@@ -35,6 +35,7 @@ export default () =>
|
|
|
35
35
|
contain="$_contain"
|
|
36
36
|
:wordWrap="$wordwrap"
|
|
37
37
|
:maxLines="$maxlines"
|
|
38
|
+
:h="$maxheight"
|
|
38
39
|
:textAlign="$align"
|
|
39
40
|
:overflowSuffix="$textoverflow"
|
|
40
41
|
@loaded="$@loaded"
|
|
@@ -59,6 +60,7 @@ export default () =>
|
|
|
59
60
|
'align',
|
|
60
61
|
'wordwrap',
|
|
61
62
|
'maxlines',
|
|
63
|
+
'maxheight',
|
|
62
64
|
'lineheight',
|
|
63
65
|
'contain',
|
|
64
66
|
'@loaded',
|
|
@@ -69,7 +71,7 @@ export default () =>
|
|
|
69
71
|
_contain() {
|
|
70
72
|
return (
|
|
71
73
|
this.contain ||
|
|
72
|
-
(this.
|
|
74
|
+
(this.maxheight && this.wordwrap ? 'both' : this.wordwrap ? 'width' : 'none')
|
|
73
75
|
)
|
|
74
76
|
},
|
|
75
77
|
_lineheight() {
|
package/src/element.js
CHANGED
|
@@ -51,8 +51,6 @@ const unpackTransition = (obj) => {
|
|
|
51
51
|
return obj
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
let firstNode = false
|
|
55
|
-
|
|
56
54
|
const Props = {
|
|
57
55
|
set parent(v) {
|
|
58
56
|
this._props.parent = v === 'root' ? renderer.root : v.node
|
|
@@ -201,7 +199,7 @@ const Props = {
|
|
|
201
199
|
this._props.contain = v
|
|
202
200
|
},
|
|
203
201
|
set maxLines(v) {
|
|
204
|
-
this.
|
|
202
|
+
this._props.maxLines = v
|
|
205
203
|
},
|
|
206
204
|
set overflowSuffix(v) {
|
|
207
205
|
this._props.overflowSuffix = v === false ? ' ' : v === true ? undefined : v
|
|
@@ -247,13 +245,6 @@ const Element = {
|
|
|
247
245
|
this.props._set.has('src') || this.props._set.has('texture') ? 0xffffffff : 0
|
|
248
246
|
}
|
|
249
247
|
|
|
250
|
-
// temporary workaround for renderer issue https://github.com/lightning-js/renderer/issues/123
|
|
251
|
-
if (!firstNode) {
|
|
252
|
-
this.props._props.src =
|
|
253
|
-
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII='
|
|
254
|
-
firstNode = true
|
|
255
|
-
}
|
|
256
|
-
|
|
257
248
|
this.node = props.__textnode
|
|
258
249
|
? renderer.createTextNode(this.props._props)
|
|
259
250
|
: renderer.createNode(this.props._props)
|
package/src/focus.js
CHANGED
|
@@ -35,7 +35,7 @@ export default {
|
|
|
35
35
|
},
|
|
36
36
|
set(component, event) {
|
|
37
37
|
clearTimeout(setFocusTimeout)
|
|
38
|
-
focusedComponent && focusedComponent.unfocus()
|
|
38
|
+
focusedComponent && focusedComponent !== component.parent && focusedComponent.unfocus()
|
|
39
39
|
focusChain.reverse().forEach((cmp) => cmp.unfocus())
|
|
40
40
|
if (component !== focusedComponent) {
|
|
41
41
|
setFocusTimeout = setTimeout(
|
package/src/router/router.js
CHANGED
|
@@ -36,17 +36,68 @@ export const getHash = () => {
|
|
|
36
36
|
return (document.location.hash || '/').replace(/^#/, '')
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
const normalizePath = (path) => {
|
|
40
|
+
return (
|
|
41
|
+
path
|
|
42
|
+
// remove leading and trailing slashes
|
|
43
|
+
.replace(/^\/+|\/+$/g, '')
|
|
44
|
+
.toLowerCase()
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
39
48
|
export const matchHash = (path, routes = []) => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
route
|
|
47
|
-
|
|
49
|
+
// remove trailing slashes
|
|
50
|
+
const originalPath = path
|
|
51
|
+
path = normalizePath(path)
|
|
52
|
+
let matchingRoute = false
|
|
53
|
+
let i = 0
|
|
54
|
+
while (!matchingRoute && i < routes.length) {
|
|
55
|
+
const route = routes[i]
|
|
56
|
+
route.path = normalizePath(route.path)
|
|
57
|
+
if (route.path === path) {
|
|
58
|
+
matchingRoute = route
|
|
59
|
+
} else if (route.path.indexOf(':') > -1) {
|
|
60
|
+
// match dynamic route parts
|
|
61
|
+
const dynamicRouteParts = [...route.path.matchAll(/:([^\s/]+)/gi)]
|
|
62
|
+
|
|
63
|
+
// construct a regex for the route with dynamic parts
|
|
64
|
+
let dynamicRoutePartsRegex = route.path
|
|
65
|
+
dynamicRouteParts.reverse().forEach((part) => {
|
|
66
|
+
dynamicRoutePartsRegex =
|
|
67
|
+
dynamicRoutePartsRegex.substring(0, part.index) +
|
|
68
|
+
'([^\\s/]+)' +
|
|
69
|
+
dynamicRoutePartsRegex.substring(part.index + part[0].length)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
// test if the constructed regex matches the path
|
|
73
|
+
const match = originalPath.match(new RegExp(`${dynamicRoutePartsRegex}`, 'i'))
|
|
74
|
+
|
|
75
|
+
if (match) {
|
|
76
|
+
// map the route params to a params object
|
|
77
|
+
route.params = dynamicRouteParts.reverse().reduce((acc, part, index) => {
|
|
78
|
+
acc[part[1]] = match[index + 1]
|
|
79
|
+
return acc
|
|
80
|
+
}, {})
|
|
81
|
+
matchingRoute = route
|
|
82
|
+
}
|
|
83
|
+
} else if (route.path.endsWith('*')) {
|
|
84
|
+
const regex = new RegExp(route.path.replace(/\/?\*/, '/?([^\\s]*)'), 'i')
|
|
85
|
+
const match = path.match(regex)
|
|
86
|
+
|
|
87
|
+
if (match) {
|
|
88
|
+
if (match[1]) route.params = { path: match[1] }
|
|
89
|
+
matchingRoute = route
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
i++
|
|
48
93
|
}
|
|
49
|
-
|
|
94
|
+
|
|
95
|
+
if (matchingRoute) {
|
|
96
|
+
matchingRoute.options = { ...matchingRoute.options, ...overrideOptions }
|
|
97
|
+
currentRoute = matchingRoute
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return matchingRoute
|
|
50
101
|
}
|
|
51
102
|
|
|
52
103
|
export const navigate = async function () {
|
|
@@ -81,16 +132,18 @@ export const navigate = async function () {
|
|
|
81
132
|
holder.populate({})
|
|
82
133
|
holder.set('w', '100%')
|
|
83
134
|
holder.set('h', '100%')
|
|
84
|
-
|
|
135
|
+
// merge props with potential route params to be injected into the component instance
|
|
136
|
+
const props = { ...this[symbols.props], ...route.params }
|
|
137
|
+
view = await route.component({ props }, holder, this)
|
|
85
138
|
if (view[Symbol.toStringTag] === 'Module') {
|
|
86
139
|
if (view.default && typeof view.default === 'function') {
|
|
87
|
-
view = view.default(
|
|
140
|
+
view = view.default({ props }, holder, this)
|
|
88
141
|
} else {
|
|
89
142
|
Log.error("Dynamic import doesn't have a default export or default is not a function")
|
|
90
143
|
}
|
|
91
144
|
}
|
|
92
145
|
if (typeof view === 'function') {
|
|
93
|
-
view = view(
|
|
146
|
+
view = view({ props }, holder, this)
|
|
94
147
|
}
|
|
95
148
|
} else {
|
|
96
149
|
holder = view[symbols.wrapper]
|
|
@@ -207,7 +260,13 @@ export const back = () => {
|
|
|
207
260
|
if (route) {
|
|
208
261
|
// set indicator that we are navigating back (to prevent adding page to history stack)
|
|
209
262
|
navigatingBack = true
|
|
210
|
-
|
|
263
|
+
let targetRoutePath = route.path
|
|
264
|
+
if (targetRoutePath.indexOf(':') > -1) {
|
|
265
|
+
Object.keys(route.params).forEach((item) => {
|
|
266
|
+
targetRoutePath = targetRoutePath.replace(`:${item}`, route.params[item])
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
to(targetRoutePath)
|
|
211
270
|
return true
|
|
212
271
|
} else {
|
|
213
272
|
return false
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2024 Comcast Cable Communications Management, LLC
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import test from 'tape'
|
|
19
|
+
import { matchHash } from './router.js'
|
|
20
|
+
|
|
21
|
+
const routes = [
|
|
22
|
+
{
|
|
23
|
+
path: '/',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
path: '/page1',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
path: '/page1/subpage1',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
path: '/tv/:show/seasons/:season',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
path: '/movies/:name',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
path: '/examples/*',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
path: '/route/with/trailing/slash/',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
path: '*',
|
|
45
|
+
},
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
test('Type of matchHash', (assert) => {
|
|
49
|
+
const expected = 'function'
|
|
50
|
+
const actual = typeof matchHash
|
|
51
|
+
|
|
52
|
+
assert.equal(actual, expected, 'matchhash should be a function')
|
|
53
|
+
assert.end()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test('Match paths with static routes that have an exact match', (assert) => {
|
|
57
|
+
assert.equal(matchHash('/', routes), routes[0], 'Should return the correct route object')
|
|
58
|
+
assert.equal(matchHash('/page1', routes), routes[1], 'Should return the correct route object')
|
|
59
|
+
assert.equal(
|
|
60
|
+
matchHash('/page1/subpage1', routes),
|
|
61
|
+
routes[2],
|
|
62
|
+
'Should return the correct route object'
|
|
63
|
+
)
|
|
64
|
+
assert.end()
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('Match paths with dynamic route parts', (assert) => {
|
|
68
|
+
assert.equal(
|
|
69
|
+
matchHash('/tv/simpsons/seasons/first', routes),
|
|
70
|
+
routes[3],
|
|
71
|
+
'Should return the correct route object'
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
assert.equal(
|
|
75
|
+
matchHash('/movies/avengers-endgame', routes),
|
|
76
|
+
routes[4],
|
|
77
|
+
'Should return the correct route object'
|
|
78
|
+
)
|
|
79
|
+
assert.end()
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
test('Match paths with a wildcard asterix', (assert) => {
|
|
83
|
+
assert.equal(
|
|
84
|
+
matchHash('/examples/example1', routes),
|
|
85
|
+
routes[5],
|
|
86
|
+
'Should return the correct route object'
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
assert.equal(
|
|
90
|
+
matchHash('/examples/example1/subexample/and-another-page', routes),
|
|
91
|
+
routes[5],
|
|
92
|
+
'Should return the correct route object'
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
assert.equal(matchHash('/404', routes), routes[7], 'Should return the correct route object')
|
|
96
|
+
|
|
97
|
+
assert.equal(
|
|
98
|
+
matchHash('/page1/subpage1/i-dont-exist', routes),
|
|
99
|
+
routes[7],
|
|
100
|
+
'Should return the correct route object'
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
assert.end()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
test('Add params to route for dynamic route matches', (assert) => {
|
|
107
|
+
const match1 = matchHash('/tv/simpsons/seasons/first', routes)
|
|
108
|
+
|
|
109
|
+
assert.deepEqual(
|
|
110
|
+
match1.params,
|
|
111
|
+
{
|
|
112
|
+
show: 'simpsons',
|
|
113
|
+
season: 'first',
|
|
114
|
+
},
|
|
115
|
+
'Should return the correct params object'
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
const match2 = matchHash('/movies/avengers-endgame', routes)
|
|
119
|
+
assert.deepEqual(
|
|
120
|
+
match2.params,
|
|
121
|
+
{
|
|
122
|
+
name: 'avengers-endgame',
|
|
123
|
+
},
|
|
124
|
+
'Should return the correct route object'
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
assert.end()
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
test('Add remaining path as param for wild card routes', (assert) => {
|
|
131
|
+
const match1 = matchHash('/examples/example1', routes)
|
|
132
|
+
assert.deepEqual(match1.params, { path: 'example1' }, 'Should return the correct route object')
|
|
133
|
+
|
|
134
|
+
const match2 = matchHash('/examples/example1/subexample/and-another-page', routes)
|
|
135
|
+
assert.deepEqual(
|
|
136
|
+
match2.params,
|
|
137
|
+
{ path: 'example1/subexample/and-another-page' },
|
|
138
|
+
'Should return the correct params object'
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
const match3 = matchHash('/404', routes)
|
|
142
|
+
assert.deepEqual(match3.params, { path: '404' }, 'Should return the correct params object')
|
|
143
|
+
|
|
144
|
+
const match4 = matchHash('/page1/subpage1/i-dont-exist', routes)
|
|
145
|
+
assert.deepEqual(
|
|
146
|
+
match4.params,
|
|
147
|
+
{ path: 'page1/subpage1/i-dont-exist' },
|
|
148
|
+
'Should return the correct params object'
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
assert.end()
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
test('Work with trailing slashes', (assert) => {
|
|
155
|
+
assert.equal(matchHash('/page1/', routes), routes[1], 'Should return the correct route object')
|
|
156
|
+
assert.equal(
|
|
157
|
+
matchHash('/page1//////', routes),
|
|
158
|
+
routes[1],
|
|
159
|
+
'Should return the correct route object'
|
|
160
|
+
)
|
|
161
|
+
assert.equal(
|
|
162
|
+
matchHash('/page1/subpage1/', routes),
|
|
163
|
+
routes[2],
|
|
164
|
+
'Should return the correct route object'
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
assert.equal(
|
|
168
|
+
matchHash('/route/with/trailing/slash', routes),
|
|
169
|
+
routes[6],
|
|
170
|
+
'Should return the correct route object'
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
assert.end()
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('Work with and without leading slashes', (assert) => {
|
|
177
|
+
assert.equal(matchHash('page1/', routes), routes[1], 'Should return the correct route object')
|
|
178
|
+
|
|
179
|
+
assert.equal(matchHash('////page1', routes), routes[1], 'Should return the correct route object')
|
|
180
|
+
assert.equal(
|
|
181
|
+
matchHash('page1/subpage1/', routes),
|
|
182
|
+
routes[2],
|
|
183
|
+
'Should return the correct route object'
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
assert.equal(
|
|
187
|
+
matchHash('route/with/trailing/slash', routes),
|
|
188
|
+
routes[6],
|
|
189
|
+
'Should return the correct route object'
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
assert.end()
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
test('Match routes case insensitive', (assert) => {
|
|
196
|
+
assert.equal(matchHash('/', routes), routes[0], 'Should return the correct route object')
|
|
197
|
+
assert.equal(matchHash('/Page1', routes), routes[1], 'Should return the correct route object')
|
|
198
|
+
assert.equal(
|
|
199
|
+
matchHash('/pagE1/SUBpage1', routes),
|
|
200
|
+
routes[2],
|
|
201
|
+
'Should return the correct route object'
|
|
202
|
+
)
|
|
203
|
+
assert.equal(
|
|
204
|
+
matchHash('/Tv/SimpsonS/Seasons/First', routes),
|
|
205
|
+
routes[3],
|
|
206
|
+
'Should return the correct route object'
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
assert.equal(
|
|
210
|
+
matchHash('/Movies/Avengers-Endgame', routes),
|
|
211
|
+
routes[4],
|
|
212
|
+
'Should return the correct route object'
|
|
213
|
+
)
|
|
214
|
+
assert.end()
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
test('Match routes case insensitive, but pass props with original casing', (assert) => {
|
|
218
|
+
const match1 = matchHash('/Tv/SimpsonS/Seasons/First', routes)
|
|
219
|
+
assert.deepEqual(
|
|
220
|
+
match1.params,
|
|
221
|
+
{
|
|
222
|
+
show: 'SimpsonS',
|
|
223
|
+
season: 'First',
|
|
224
|
+
},
|
|
225
|
+
'Should return the correct params object'
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
const match2 = matchHash('/Movies/Avengers-Endgame', routes)
|
|
229
|
+
assert.deepEqual(
|
|
230
|
+
match2.params,
|
|
231
|
+
{
|
|
232
|
+
name: 'Avengers-Endgame',
|
|
233
|
+
},
|
|
234
|
+
'Should return the correct params object'
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
assert.end()
|
|
238
|
+
})
|