Skip to content

Commit

Permalink
Add tests for Json type
Browse files Browse the repository at this point in the history
  • Loading branch information
Mrtenz committed Oct 6, 2022
1 parent ad5fc45 commit 732837e
Show file tree
Hide file tree
Showing 4 changed files with 528 additions and 10 deletions.
5 changes: 4 additions & 1 deletion package.json
Expand Up @@ -22,7 +22,9 @@
"lint:fix": "yarn lint:eslint --fix && yarn lint:misc --write",
"lint:misc": "prettier '**/*.json' '**/*.md' '!CHANGELOG.md' '**/*.yml' --ignore-path .gitignore",
"prepublishOnly": "yarn build:clean && yarn lint && yarn test",
"test": "jest",
"test": "yarn test:source && yarn test:types",
"test:source": "jest",
"test:types": "tsd test-d --typings \"json.test-d.ts\" --files \"**/*.test-d.ts\"",
"test:watch": "jest --watch"
},
"resolutions": {
Expand Down Expand Up @@ -58,6 +60,7 @@
"rimraf": "^3.0.2",
"stdio-mock": "^1.2.0",
"ts-jest": "^28.0.8",
"tsd": "^0.24.1",
"typedoc": "^0.23.10",
"typescript": "~4.7.4"
},
Expand Down
135 changes: 135 additions & 0 deletions test-d/json.test-d.ts
@@ -0,0 +1,135 @@
/* eslint-disable @typescript-eslint/consistent-type-definitions */

import { expectAssignable, expectNotAssignable } from 'tsd';
import type { Json } from '../src';

// Valid Json:

expectAssignable<Json>(null);

expectAssignable<Json>(false);

expectAssignable<Json>('');

expectAssignable<Json>(0);

expectAssignable<Json>([]);

expectAssignable<Json>({});

expectAssignable<Json>([0]);

expectAssignable<Json>({ a: 0 });

expectAssignable<Json>({ deeply: [{ nested: 1 }, 'mixed', 'types', 0] });

expectAssignable<Json>(['array', { nested: { mixed: true, types: null } }, 0]);

type JsonCompatibleType = {
c: number;
};
const jsonCompatibleType: JsonCompatibleType = { c: 0 };
expectAssignable<Json>(jsonCompatibleType);

// Invalid Json:

expectNotAssignable<Json>(undefined);

expectNotAssignable<Json>(new Date());

expectNotAssignable<Json>(() => 0);

expectNotAssignable<Json>(new Set());

expectNotAssignable<Json>(new Map());

expectNotAssignable<Json>(Symbol('test'));

expectNotAssignable<Json>({ a: new Date() });

expectNotAssignable<Json>(5 as number | undefined);

interface InterfaceWithOptionalProperty {
a?: number;
}
const interfaceWithOptionalProperty: InterfaceWithOptionalProperty = { a: 0 };
expectNotAssignable<Json>(interfaceWithOptionalProperty);

interface InterfaceWithDate {
a: Date;
}
const interfaceWithDate: InterfaceWithDate = { a: new Date() };
expectNotAssignable<Json>(interfaceWithDate);

interface InterfaceWithOptionalDate {
a?: Date;
}
const interfaceWithOptionalDate: InterfaceWithOptionalDate = { a: new Date() };
expectNotAssignable<Json>(interfaceWithOptionalDate);

interface InterfaceWithUndefinedTypeUnion {
a: number | undefined;
}
const interfaceWithUndefinedTypeUnion: InterfaceWithUndefinedTypeUnion = {
a: 0,
};
expectNotAssignable<Json>(interfaceWithUndefinedTypeUnion);

interface InterfaceWithFunction {
a: () => number;
}
const interfaceWithFunction: InterfaceWithFunction = { a: () => 0 };
expectNotAssignable<Json>(interfaceWithFunction);

type TypeWithDate = {
a: Date;
};
const typeWithDate: TypeWithDate = { a: new Date() };
expectNotAssignable<Json>(typeWithDate);

type TypeWithOptionalDate = {
a?: Date;
};
const typeWithOptionalDate: TypeWithOptionalDate = { a: new Date() };
expectNotAssignable<Json>(typeWithOptionalDate);

type TypeWithUndefinedTypeUnion = {
a: number | undefined;
};
const typeWithUndefinedTypeUnion: TypeWithUndefinedTypeUnion = {
a: 0,
};
expectNotAssignable<Json>(typeWithUndefinedTypeUnion);

type TypeWithFunction = {
a: () => number;
};
const typeWithFunction: TypeWithFunction = { a: () => 0 };
expectNotAssignable<Json>(typeWithFunction);

type TypeWithOptionalProperty = {
a?: number | undefined;
};
const typeWithOptionalProperty: TypeWithOptionalProperty = { a: undefined };
expectNotAssignable<Json>(typeWithOptionalProperty);

// Edge cases:

// The Json type doesn't protect against the `any` type.
expectAssignable<Json>(null as any);

// The Json type gets confused by interfaces. This interface is valid Json,
// but it's incompatible with the Json type.
interface A {
a: number;
}
const a: A = { a: 0 };
expectNotAssignable<Json>(a);

// The Json type gets confused by classes. This class instance is valid Json,
// but it's incompatible with the Json type.
class B {
a!: number;
}
const b = new B();
expectNotAssignable<Json>(b);
4 changes: 4 additions & 0 deletions test-d/package.json
@@ -0,0 +1,4 @@
{
"name": "test-d",
"private": true
}

0 comments on commit 732837e

Please sign in to comment.