Skip to content

Commit

Permalink
chore: refactor to work with abstract-nested-router
Browse files Browse the repository at this point in the history
  • Loading branch information
pateketrueke committed Jun 26, 2022
1 parent 8e1b907 commit 46287f3
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 91 deletions.
16 changes: 15 additions & 1 deletion e2e/cases/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ test('it should mount nested content', async t => {
await t.click(Selector('a').withText('Link'));
await t.expect(Selector('[data-test=example]').withText('Hello a').visible).ok();
await t.expect(Selector('[data-test=counter]').innerText).contains(2);
await t.expect(Selector('[data-test=unordered]').innerText).notContains('III');

await t.click(Selector('a').withText('List'));
await t.expect(Selector('[data-test=unordered]').innerText).eql('III');

await t.click(Selector('a').withText('Show'));
await t.expect(Selector('[data-test=unordered]').innerText).eql('II III');

await t.click(Selector('a').withText('Edit'));
await t.expect(Selector('[data-test=unordered]').innerText).eql('I II III');
});

test('it should fallback on unmatched routes', async t => {
Expand Down Expand Up @@ -169,21 +179,25 @@ fixture('yrv (nested routes)')
.page(url('/top'));

test('it should nothing at top-level', async t => {
await t.expect(Selector('p[data-test=nested]').innerText).contains('?');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('a');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('b');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('c');

await t.click(Selector('a').withText('1'));
await t.expect(Selector('p[data-test=nested]').innerText).notContains('?');
await t.expect(Selector('p[data-test=nested]').innerText).contains('a');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('b');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('c');

await t.click(Selector('a').withText('2'));
await t.expect(Selector('p[data-test=nested]').innerText).notContains('?');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('a');
await t.expect(Selector('p[data-test=nested]').innerText).contains('b');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('c');

await t.click(Selector('a').withText('3'));
await t.expect(Selector('p[data-test=nested]').innerText).notContains('?');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('a');
await t.expect(Selector('p[data-test=nested]').innerText).notContains('b');
await t.expect(Selector('p[data-test=nested]').innerText).contains('c');
Expand All @@ -195,7 +209,7 @@ fixture('yrv (hashed routes)')

test('it should load root-handlers', async t => {
await t.expect(Selector('[data-test=hashed]').innerText).contains('GIST INFO');
await t.expect(Selector('[data-test=hashed]').innerText).notContains('SHA1');
await t.expect(Selector('[data-test=hashed]').innerText).notContains('SHA1: N/A');
await t.expect(Selector('[data-test=hashed]').innerText).notContains('(edit)');
await t.expect(Selector('[data-test=hashed]').innerText).notContains('(save)');
await t.expect(Selector('[data-test=counter]').innerText).contains(1);
Expand Down
2 changes: 1 addition & 1 deletion e2e/components/Import.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

<div data-test="container">
<Router pending="Loading...">
<Route fallback component={() => delay(import('./Example.svelte'))} />
<Route key="imported" fallback component={() => delay(import('./Example.svelte'))} />
</Router>
</div>
84 changes: 52 additions & 32 deletions e2e/components/Main.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<script>
import { Router, Route, Link, router } from 'yrv';
import {
Router, Route, Link, router,
} from 'yrv';
import Testing from './Testing.svelte';
Expand Down Expand Up @@ -35,9 +37,9 @@
<Link exact href="/example/a">Link</Link> | <Link exact href="/example/a/b">Broken link</Link>

<p data-test="example">
<Route exact>Hello World</Route>
<Route fallback>Not found</Route>
<Route exact path="/:name" let:router>Hello {router.params.name}</Route>
<Route key="not-found" fallback>Not found?</Route>
<Route key="hello-world" exact>Hello World</Route>
<Route key="hello-name" exact path="/:name" let:router>Hello {router.params.name}</Route>
</p>
</Router>

Expand All @@ -47,6 +49,7 @@
<Link href="/top/foo/a">1</Link>
| <Link href="/top/bar/b">2</Link>
| <Link href="/top/bar/c">3</Link>
| <Link href="/top">?</Link>
</p>

<p>
Expand All @@ -56,15 +59,16 @@
</p>

<p data-test="nested">
<Router path="/top">
<Route path="/foo/a">a</Route>
<Route path="/bar/b">b</Route>
<Route path="/bar/c">c</Route>
<Router key="top" path="/top">
<Route key="x" exact fallback>?</Route>
<Route key="a" exact path="/foo/a">a</Route>
<Route key="b" exact path="/bar/b">b</Route>
<Route key="c" exact path="/bar/c">c</Route>
</Router>
</p>

<Router path="/test" nofallback>
<Route>
<Route key="test-root">
<h2>Testing features</h2>

<p>This content is always mounted when the current URL starts-with <tt>/test</tt>.</p>
Expand All @@ -75,28 +79,35 @@
| <Link href="/test/dynamic">Protected</Link>

<p data-test="redirect">
<Route path="/failed">Wrong!</Route>
<Route path="/static" redirect="/test" />
<Route path="/dynamic" redirect="/test/failed" condition={() => /* eslint-disable no-alert */ window.confirm('Are you sure?')}>Yay!</Route>
<Route key="failed" path="/failed">Wrong!</Route>
<Route key="static" path="/static" redirect="/test" />
<Route key="dynamic" path="/dynamic" redirect="/test/failed" condition={() => /* eslint-disable no-alert */ window.confirm('Are you sure?')}>Yay!</Route>
</p>
</Route>

<Route path="/props" component={Testing} />
<Route key="props" path="/props" component={Testing} />

<p data-test="routeless">Any <tt>Route</tt>-less content is always shown!</p>
</Router>

<div data-test="hashed">
<Router path="/gist">
<Route exact>GIST INFO</Route>
<Router key="gist" path="/gist">
<Route key="main" exact>GIST INFO</Route>
<Router path="#:sha1" nofallback>
<Route let:router>SHA1: {router.params.sha1 || 'N/A'}</Route>
<Route exact path="/edit">(edit)</Route>
<Route exact path="/save">(save)</Route>
<Route key="show" let:router>SHA1: {router.params.sha1 || 'N/A'}</Route>
<Route key="edit" exact path="/edit">(edit)</Route>
<Route key="save" exact path="/save">(save)</Route>
</Router>
</Router>
</div>

<Link exact href="/gist">gists</Link>
| <Link href="/gist#x" exact>gshow</Link>
| <Link href="/gist#x/edit">gedit</Link>
| <Link href="/gist#x/save">gsave</Link>

<hr />

<div data-test="logged">
<label>
<input type="checkbox" bind:checked={loggedIn} /> on/off
Expand All @@ -108,40 +119,37 @@
| <Link href="/auth/protected">Protected page</Link>

<Router path="/auth">
{#if !loggedIn}
<Route exact redirect="/auth/login" />
{:else}
<Route exact>Welcome back.</Route>
{/if}

<Route path="/protected" condition={() => loggedIn} redirect="/auth/login">O.K.</Route>
<Route path="/login">Log-in</Route>
<Route key="secure" path="/protected" condition={() => loggedIn} redirect="/auth/login">O.K.</Route>
<Route key="login" path="/login">Log-in</Route>

<Route key="check" condition={() => loggedIn} exact redirect="/auth/login" />
<Route key="welcome" disabled={!loggedIn} exact>Welcome back.</Route>
</Router>
</div>

<Router disabled={!loggedIn}>
<p data-test="secret">
<Route>Shhhh! Top-secret</Route>
<Route key="sh">Shhhh! Top-secret</Route>
</p>
</Router>

<Router path="/sub">
<Route>
<Route key="sub">
<Link exact href="/sub#">Root</Link> | <Link href="/sub#/about">About page</Link> | <Link href="/sub#broken">Broken anchor</Link>
</Route>

<p data-test="anchored">
<Route exact path="#">HOME</Route>
<Route exact path="#/about">ABOUT</Route>
<Route key="home" exact path="#">HOME</Route>
<Route key="about" exact path="#/about">ABOUT</Route>
</p>
</Router>

<Router path="/e">
<Route exact>
<Route key="err" exact>
<h2>It works!</h2>
</Route>

<Route fallback>
<Route key="404" fallback>
<h2 data-test="fallback">NOT FOUND</h2>
</Route>
</Router>
Expand All @@ -151,4 +159,16 @@
<p data-test="counter">Times router-info has been changed: {count}</p>
</div>

<p data-test="unordered">
<Router path="/page">
<Route key="i" path="/:x/:y">I</Route>
<Route key="ii" path="/:x">II</Route>
<Route key="iii" path="/">III</Route>
</Router>
</p>

<Link href="/page">List</Link>
<Link href="/page/1">Show</Link>
<Link href="/page/1/edit">Edit</Link>

<a style="margin-top:1000px;display:block" href="#top">&uarr;</a>
2 changes: 1 addition & 1 deletion e2e/components/Testing.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
</fieldset>

<Router>
<Route path="/:value" let:router>
<Route key="test-info" path="/:value" let:router>
<p>Value: {router.params.value}</p>
</Route>
</Router>
10 changes: 5 additions & 5 deletions e2e/components/nested-routers/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@
let isLoggedIn = true;
</script>

<Link>Home</Link> |
<Link href="/">Home</Link> |
<Link href="/players">Players</Link> |
<Link href="/notfound">Not found</Link> |
<input type="checkbox" bind:checked={isLoggedIn}> isLoggedIn

<Router>
{#if isLoggedIn}
<Route exact component="{Home}" />
<Route path="/players" component="{Players}" />
<Route key="fixed" fallback component={NotFound} />
<Route key="home" exact component="{Home}" />
<Route key="players" path="/players" component="{Players}" />
<Route key="404" fallback component={NotFound} />
{:else}
<Route key="fixed" fallback component={Login} />
<Route key="ask" fallback component={Login} />
{/if}
</Router>
4 changes: 2 additions & 2 deletions e2e/components/nested-routers/Players.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<Link href="/players/team/new">New Team</Link>

<Router>
<Route exact component="{List}" />
<Route path="/team/new" exact component="{NewTeam}" />
<Route key="list" exact component="{List}" />
<Route key="new" path="/team/new" exact component="{NewTeam}" />
</Router>
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yrv",
"version": "0.0.52",
"version": "0.0.53",
"description": "Your routing!",
"types": "types/index.d.ts",
"_main": "build/dist/index.js",
Expand All @@ -27,7 +27,8 @@
"build:test": "npm run mortero -- src e2e -X{lib,cases,components} -Xhelpers.js -X'**/_*'",
"build:all": "mortero src/lib -fKXtest -Dbuild/dist --format esm --platform browser",
"build": "npm run build:all && npm run build:debug && npm run build:module",
"test": "npm run build:test -- -fyjs && testcafe ${BROWSER:-chrome:headless} --color -q -a 'npm run dev' e2e/cases"
"test:e2e": "testcafe ${BROWSER:-chrome:headless} --color -q",
"test": "npm run build:test -- -fyjs && npm run test:e2e -- -a 'npm run dev' e2e/cases"
},
"mortero": {
"bundle": [
Expand Down Expand Up @@ -62,7 +63,7 @@
"svelte": "3.x"
},
"devDependencies": {
"abstract-nested-router": "^0.1.20",
"abstract-nested-router": "^0.2.1",
"eslint": "^7.27.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.18.2",
Expand Down
14 changes: 13 additions & 1 deletion src/lib/Route.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { writable } from 'svelte/store';
import { routeInfo } from './router';
import {
CTX_ROUTER, CTX_ROUTE, getProps, isPromise, isSvelteComponent,
CTX_ROUTER, CTX_ROUTE, router, getProps, isPromise, isSvelteComponent,
} from './utils';
</script>

Expand Down Expand Up @@ -68,6 +68,10 @@
throw new TypeError(`Missing top-level <Router>, given route: ${path}`);
}
if (!key) {
throw new TypeError(`Expecting a key per-route definition, given route: ${path}`);
}
resolve();
} catch (e) {
failure = e;
Expand All @@ -84,6 +88,12 @@
}
$: if (activeRouter) {
for (const k in $router.params) {
if (typeof activeRouter.params[k] === 'undefined') {
activeRouter.params[k] = $router.params[k];
}
}
if (!component) { // component passed as slot
hasLoaded = true;
} else if (isSvelteComponent(component)) { // component passed as Svelte component
Expand Down Expand Up @@ -125,6 +135,7 @@
<!--ENDIF-->

{#if activeRouter}
<!--<fieldset><legend>{key} ({exact} | {fullpath})</legend>-->
{#if !hasLoaded}
{#if pending || pendingComponent}
{#if isSvelteComponent(pending)}
Expand All @@ -142,4 +153,5 @@
<slot {...activeProps} />
{/if}
{/if}
<!--</fieldset>-->
{/if}
19 changes: 9 additions & 10 deletions src/lib/Router.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import {
baseRouter, addRouter, findRoutes, doFallback,
} from './router';
// const __CACHED_ROUTES__ = new Map();
</script>

<script>
Expand All @@ -15,6 +17,7 @@
let failure;
let fallback;
export let key = '';
export let path = '/';
export let pending = null;
export let disabled = false;
Expand Down Expand Up @@ -45,23 +48,19 @@
}
// ENDIF
function assignRoute(key, route, detail) {
key = key || Math.random().toString(36).substr(2);
// consider as nested routes if they does not have any segment
const nested = !route.substr(1).includes('/');
const handler = { key, nested, ...detail };
function assignRoute(_key, route, detail) {
const $key = [key, _key].filter(Boolean).join('.');
const handler = { key: $key, ...detail };
let fullpath;
baseRouter.mount(fixedRoot, () => {
fullpath = baseRouter.add(route, handler);
fallback = (handler.fallback && key) || fallback;
fallback = (handler.fallback && $key) || fallback;
});
findRoutes();
return [key, fullpath];
return [$key, fullpath];
}
function unassignRoute(route) {
Expand Down Expand Up @@ -102,7 +101,7 @@
</script>

{#if !disabled}
<slot />
<slot router={$router} />
{/if}

<!--IF DEBUG-->
Expand Down

0 comments on commit 46287f3

Please sign in to comment.