Skip to content

Commit

Permalink
Tate/tests (#21)
Browse files Browse the repository at this point in the history
* update dev deps

* v0.0.14

* add type tests
  • Loading branch information
tatethurston authored Jul 7, 2022
1 parent ff59322 commit b618e60
Show file tree
Hide file tree
Showing 16 changed files with 506 additions and 116 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// eslint-disable-next-line no-undef
module.exports = {
root: true,
ignorePatterns: ["dist", "examples"],
ignorePatterns: ["dist", "examples", "e2e"],
plugins: ["@typescript-eslint"],
extends: [
"eslint:recommended",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
dist
coverage
node_modules
tsconfig.tsbuildinfo
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ This means replacing imports of `next/link` with `nextjs-routes/link` and `next/
+import { useRouter } from 'next/router'
```

- Added windows support
- Added windows support.
17 changes: 17 additions & 0 deletions e2e/e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { spawnSync } from "child_process";

function run(cmd: string) {
return spawnSync(cmd, { shell: true, encoding: "utf8" });
}

describe("e2e", () => {
process.chdir(__dirname);

it.each(["node ../dist/cli.js", "yarn tsc --noEmit"])("%s", (cmd) => {
const result = run(cmd);
if (result.status !== 0) {
console.log(result.output);
}
expect(result.status).toEqual(0);
});
});
66 changes: 66 additions & 0 deletions e2e/nextjs-routes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.'
// Run `yarn nextjs-routes` to regenerate this file.
/* eslint-disable */

type Route =
| { pathname?: "/foos/[foo]"; query: Query<{ foo: string }> }
| { pathname?: "/"; query?: Query | undefined };

type Query<Params = {}> = Params & {
[key: string]: string;
};

type Pathname = Exclude<Route["pathname"], undefined>;

type QueryForPathname = {
[K in Route as K["pathname"]]: Exclude<K["query"], undefined>;
};

declare module "next/link" {
import type { LinkProps as NextLinkProps } from "next/dist/client/link";
import type { PropsWithChildren, MouseEventHandler } from "react";

export interface LinkProps extends Omit<NextLinkProps, "href"> {
href: Route;
}

declare function Link(
props: PropsWithChildren<LinkProps>
): DetailedReactHTMLElement<
{
onMouseEnter?: MouseEventHandler<Element> | undefined;
onClick: MouseEventHandler;
href?: string | undefined;
ref?: any;
},
HTMLElement
>;

export default Link;
}

declare module "next/router" {
import type { NextRouter as Router } from "next/dist/client/router";
export { RouterEvent } from "next/dist/client/router";

type TransitionOptions = Parameters<Router["push"]>[2];

export interface NextRouter<P extends Pathname = Pathname>
extends Omit<Router, "push" | "replace"> {
pathname: P;
route: P;
query: QueryForPathname[P];
push(
url: Route,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
replace(
url: Route,
as?: string,
options?: TransitionOptions
): Promise<boolean>;
}

export function useRouter<P extends Pathname>(): NextRouter<P>;
}
14 changes: 14 additions & 0 deletions e2e/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "e2e",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"next": "*",
"react": "*",
"react-dom": "*"
},
"devDependencies": {
"typescript": "*"
}
}
1 change: 1 addition & 0 deletions e2e/pages/foos/[foo].ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
1 change: 1 addition & 0 deletions e2e/pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
20 changes: 20 additions & 0 deletions e2e/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}
85 changes: 85 additions & 0 deletions e2e/typetest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import Link from "next/link";
import { useRouter } from "next/router";

// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
function expectType<T>(_value: T) {}

// next/link

// Path without dynamic segments
<Link href={{ pathname: "/" }} />;
<Link href={{ pathname: "/", query: undefined }} />;
<Link href={{ pathname: "/", query: {} }} />;
<Link href={{ pathname: "/", query: { bar: "baz" } }} />;

// Path with dynamic segments
<Link href={{ pathname: "/foos/[foo]", query: { foo: "baz" } }} />;
// @ts-expect-error missing 'foo' in query
<Link href={{ pathname: "/foos/[foo]", query: { bar: "baz" } }} />;
// @ts-expect-error missing 'foo' in query
<Link href={{ pathname: "/foos/[foo]", query: undefined }} />;
// @ts-expect-error missing 'foo' in query
<Link href={{ pathname: "/foos/[foo]", query: {} }} />;
<Link href={{ pathname: "/foos/[foo]", query: { foo: "baz", bar: "baz" } }} />;

// Only change query for current page
<Link href={{ query: { bar: "baz" } }} />;
<Link href={{ query: { foo: "foo" } }} />;

// next/router
const router = useRouter();

// pathname
expectType<"/" | "/foos/[foo]">(router.pathname);

// route
expectType<"/" | "/foos/[foo]">(router.route);

// query
expectType<{ foo: string; [key: string]: string } | { [key: string]: string }>(
router.query
);

// push

// Path without dynamic segments
router.push({ pathname: "/" });
router.push({ pathname: "/", query: undefined });
router.push({ pathname: "/", query: {} });
router.push({ pathname: "/", query: { bar: "baz" } });

// Path with dynamic segments
router.push({ pathname: "/foos/[foo]", query: { foo: "baz" } });
// @ts-expect-error missing 'foo' in query
router.push({ pathname: "/foos/[foo]", query: { bar: "baz" } });
// @ts-expect-error missing 'foo' in query
router.push({ pathname: "/foos/[foo]", query: undefined });
// @ts-expect-error missing 'foo' in query
router.push({ pathname: "/foos/[foo]", query: {} });
router.push({ pathname: "/foos/[foo]", query: { foo: "baz", bar: "baz" } });

// Only change query for current page
router.push({ query: { bar: "baz" } });
router.push({ query: { foo: "foo" } });

// replace

// Path without dynamic segments
router.replace({ pathname: "/" });
router.replace({ pathname: "/", query: undefined });
router.replace({ pathname: "/", query: {} });
router.replace({ pathname: "/", query: { bar: "baz" } });

// Path with dynamic segments
router.replace({ pathname: "/foos/[foo]", query: { foo: "baz" } });
// @ts-expect-error missing 'foo' in query
router.replace({ pathname: "/foos/[foo]", query: { bar: "baz" } });
// @ts-expect-error missing 'foo' in query
router.replace({ pathname: "/foos/[foo]", query: undefined });
// @ts-expect-error missing 'foo' in query
router.replace({ pathname: "/foos/[foo]", query: {} });
router.replace({ pathname: "/foos/[foo]", query: { foo: "baz", bar: "baz" } });

// Only change query for current page
router.replace({ query: { bar: "baz" } });
router.replace({ query: { foo: "foo" } });
Loading

0 comments on commit b618e60

Please sign in to comment.