Skip to content

Commit

Permalink
Add tests for Json and Hex type (#42)
Browse files Browse the repository at this point in the history
* Add tests for Json type

* Move test to src folder and get rid of test-d folder

* Add tests for Hex type too

* Exclude type tests from coverage
  • Loading branch information
Mrtenz committed Oct 6, 2022
1 parent c971d54 commit 4136519
Show file tree
Hide file tree
Showing 5 changed files with 558 additions and 11 deletions.
6 changes: 5 additions & 1 deletion jest.config.js
Expand Up @@ -2,7 +2,11 @@ module.exports = {
collectCoverage: true,
// Ensures that we collect coverage from all source files, not just tested
// ones.
collectCoverageFrom: ['./src/**/*.ts', '!./src/__fixtures__/**/*'],
collectCoverageFrom: [
'./src/**/*.ts',
'!./src/__fixtures__/**/*',
'!./src/**/*.test-d.ts',
],
coverageReporters: ['text', 'html'],
coverageThreshold: {
global: {
Expand Down
8 changes: 7 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: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 All @@ -73,5 +76,8 @@
"allowScripts": {
"@lavamoat/preinstall-always-fail": false
}
},
"tsd": {
"directory": "src"
}
}
26 changes: 26 additions & 0 deletions src/hex.test-d.ts
@@ -0,0 +1,26 @@
import { expectAssignable, expectNotAssignable } from 'tsd';

import { Hex } from '.';

// Valid hex strings:

expectAssignable<Hex>('0x');

expectAssignable<Hex>('0x0');

expectAssignable<Hex>('0x😀');

const embeddedString = 'test';
expectAssignable<Hex>(`0x${embeddedString}`);

// Not valid hex strings:

expectNotAssignable<Hex>(`0X${embeddedString}`);

expectNotAssignable<Hex>(`1x${embeddedString}`);

expectNotAssignable<Hex>(0);

expectNotAssignable<Hex>('0');

expectNotAssignable<Hex>('🙃');
135 changes: 135 additions & 0 deletions src/json.test-d.ts
@@ -0,0 +1,135 @@
/* eslint-disable @typescript-eslint/consistent-type-definitions */

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

// 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);

0 comments on commit 4136519

Please sign in to comment.