Skip to content

Commit

Permalink
Test: TS type specification strength tests (PoC)
Browse files Browse the repository at this point in the history
  • Loading branch information
monfera committed Feb 17, 2019
1 parent 0141753 commit c1b26c1
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 2 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"test:ui:runner": "node scripts/functional_test_runner",
"test:server": "grunt test:server",
"test:coverage": "grunt test:coverage",
"typespec": "typings-tester --config x-pack/plugins/canvas/public/lib/aeroelastic/tsconfig.json x-pack/plugins/canvas/public/lib/aeroelastic/__tests__/typescript/typespec_tests.ts",
"checkLicenses": "grunt licenses --dev",
"build": "node scripts/build --all-platforms",
"start": "node --trace-warnings --trace-deprecation scripts/kibana --dev ",
Expand Down Expand Up @@ -407,6 +408,7 @@
"tslint-microsoft-contrib": "^6.0.0",
"tslint-plugin-prettier": "^2.0.0",
"typescript": "^3.0.3",
"typings-tester": "^0.3.2",
"vinyl-fs": "^3.0.2",
"xml2js": "^0.4.19",
"xmlbuilder": "9.0.4",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { select } from '../../select';
import { Json, Selector } from '../..';

/*
Type checking isn't too useful if future commits can accidentally weaken the type constraints, because a
TypeScript linter will not complain - everything that passed before will continue to pass. The coder
will not have feedback that the original intent with the typing got compromised. To declare the intent
via passing and failing type checks, test cases are needed, some of which designed to expect a TS pass,
some of them to expect a TS complaint. It documents intent for peers too, as type specs are a tough read.
Run compile-time type specification tests in the `kibana` root with:
yarn typespec
Test "cases" expecting to pass TS checks are not annotated, while ones we want TS to complain about
are prepended with the comment
// typings:expect-error
The test "suite" and "cases" are wrapped in IIFEs to prevent linters from complaining about the unused
binding. It can be structured internally as desired.
*/

((): void => {
/**
* TYPE TEST SUITE
*/

(function jsonTests(plain: Json): void {
// numbers are OK
plain = 1;
plain = NaN;
plain = Infinity;
plain = -Infinity;
plain = Math.pow(2, 6);
// other JSON primitive types are OK
plain = false;
plain = 'hello';
plain = null;
// structures made of above and of structures are OK
plain = {};
plain = [];
plain = { a: 1 };
plain = [0, null, false, NaN, 3.14, 'one more'];
plain = { a: { b: 5, c: { d: [1, 'a', -Infinity, null], e: -1 }, f: 'b' }, g: false };

// typings:expect-error
plain = undefined; // it's undefined
// typings:expect-error
plain = a => a; // it's a function
// typings:expect-error
plain = [new Date()]; // it's a time
// typings:expect-error
plain = { a: Symbol('haha') }; // symbol isn't permitted either
// typings:expect-error
plain = window || void 0;
// typings:expect-error
plain = { a: { b: 5, c: { d: [1, 'a', undefined, null] } } }; // going deep into the structure

return; // jsonTests
})(null);

(function selectTests(selector: Selector): void {
select((a: Json) => a); // one arg
select((a: Json, b: Json): Json => `${a} and ${b}`); // more args
select(() => 1); // zero arg
select((...args: Json[]) => args); // variadic

// typings:expect-error
select(() => {}); // should yield a JSON value, but it returns void
// typings:expect-error
select((x: Json) => ({ a: x, b: undefined })); // should return a Json

return; // selectTests
})(select((a: Json) => a));

return; // test suite
})();
19 changes: 19 additions & 0 deletions x-pack/plugins/canvas/public/lib/aeroelastic/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"extends": "../../../../../tsconfig",
"compilerOptions": {
"module": "commonjs",
"lib": ["esnext", "dom"],
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": false,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"forceConsistentCasingInFileNames": false,
"noEmit": true,
"baseUrl": ".",
"paths": {
"layout/*": ["aeroelastic/*"]
}
}
}
3 changes: 2 additions & 1 deletion x-pack/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"typings/**/*"
],
"exclude": [
"test/**/*"
"test/**/*",
"**/typespec_tests.ts"
],
"compilerOptions": {
"paths": {
Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5740,7 +5740,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/commander/-/commander-0.6.1.tgz#fa68a14f6a945d54dbbe50d8cdb3320e9e3b1a06"
integrity sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=

commander@2, [email protected], commander@^2.11.0, commander@^2.12.1, commander@^2.8.1, commander@^2.9.0:
commander@2, [email protected], commander@^2.11.0, commander@^2.12.1, commander@^2.12.2, commander@^2.8.1, commander@^2.9.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==
Expand Down Expand Up @@ -21723,6 +21723,13 @@ typescript@^3.0.3:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8"
integrity sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg==

typings-tester@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/typings-tester/-/typings-tester-0.3.2.tgz#04cc499d15ab1d8b2d14dd48415a13d01333bc5b"
integrity sha512-HjGoAM2UoGhmSKKy23TYEKkxlphdJFdix5VvqWFLzH1BJVnnwG38tpC6SXPgqhfFGfHY77RlN1K8ts0dbWBQ7A==
dependencies:
commander "^2.12.2"

ua-parser-js@^0.7.18, ua-parser-js@^0.7.9:
version "0.7.18"
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.18.tgz#a7bfd92f56edfb117083b69e31d2aa8882d4b1ed"
Expand Down

0 comments on commit c1b26c1

Please sign in to comment.