Skip to content

Commit

Permalink
[ts][ftr] improve types for ftr and expect.js, cleanup changes to tsc…
Browse files Browse the repository at this point in the history
…onfig files (#31948) (#32250)

In elastic/kibana#31234 there were some extra changes that I've reverted, like use of the `tsconfig-paths` package to magically rewrite import statements to defy the standard node module resolution algorithm, the inclusion of several unnecessary options in the `test/tsconfig.json` file, and changes of the line-endings in the config files. This also brings a few enhancements from elastic/kibana#30190 including a modularized version of the expect.js types, and options for explicit mappings for the PageObjects and services used in ftr tests.
  • Loading branch information
Spencer authored Feb 28, 2019
1 parent a7c02d4 commit ba82d02
Show file tree
Hide file tree
Showing 48 changed files with 1,365 additions and 768 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@
"ts-jest": "^23.1.4",
"ts-loader": "^5.2.2",
"ts-node": "^7.0.1",
"tsconfig-paths": "^3.8.0",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-microsoft-contrib": "^6.0.0",
Expand Down
42 changes: 21 additions & 21 deletions packages/kbn-config-schema/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationDir": "./target/types",
"outDir": "./target/out",
"stripInternal": true,
"declarationMap": true,
"types": [
"jest",
"node"
]
},
"include": [
"./types/joi.d.ts",
"./src/**/*.ts"
],
"exclude": [
"target"
]
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"declarationDir": "./target/types",
"outDir": "./target/out",
"stripInternal": true,
"declarationMap": true,
"types": [
"jest",
"node"
]
},
"include": [
"./types/joi.d.ts",
"./src/**/*.ts"
],
"exclude": [
"target"
]
}
6 changes: 6 additions & 0 deletions packages/kbn-test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"extends": "../../tsconfig.json",
"include": [
"types/**/*"
]
}
6 changes: 6 additions & 0 deletions packages/kbn-test/types/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# @kbn/test/types

Shared types used by different parts of the tests

- **`expect.js.d.ts`**: This is a fork of the expect.js types that have been slightly modified to only expose a module type for `import expect from 'expect.js'` statements. The `@types/expect.js` includes types for the `expect` global, which is useful for some uses of the library but conflicts with the jest types we use. Making the type "module only" prevents them from conflicting.
- **`ftr.d.ts`**: These types are generic types for using the functional test runner. They are here because we plan to move the functional test runner into the `@kbn/test` package at some point and having them here makes them a lot easier to import from all over the place like we do.
225 changes: 225 additions & 0 deletions packages/kbn-test/types/expect.js.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
// tslint:disable

// Type definitions for expect.js 0.3.1
// Project: https://github.com/Automattic/expect.js
// Definitions by: Teppei Sato <https://github.com/teppeis>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// License: MIT

declare module 'expect.js' {
function expect(target?: any): Root;

interface Assertion {
/**
* Assert typeof / instanceof.
*/
an: An;
/**
* Check if the value is truthy
*/
ok(): void;

/**
* Creates an anonymous function which calls fn with arguments.
*/
withArgs(...args: any[]): Root;

/**
* Assert that the function throws.
*
* @param fn callback to match error string against
*/
throwError(fn?: (exception: any) => void): void;

/**
* Assert that the function throws.
*
* @param fn callback to match error string against
*/
throwException(fn?: (exception: any) => void): void;

/**
* Assert that the function throws.
*
* @param regexp regexp to match error string against
*/
throwError(regexp: RegExp): void;

/**
* Assert that the function throws.
*
* @param fn callback to match error string against
*/
throwException(regexp: RegExp): void;

/**
* Checks if the array is empty.
*/
empty(): Assertion;

/**
* Checks if the obj exactly equals another.
*/
equal(obj: any): Assertion;

/**
* Checks if the obj sortof equals another.
*/
eql(obj: any): Assertion;

/**
* Assert within start to finish (inclusive).
*
* @param start
* @param finish
*/
within(start: number, finish: number): Assertion;

/**
* Assert typeof.
*/
a(type: string): Assertion;

/**
* Assert instanceof.
*/
a(type: Function): Assertion;

/**
* Assert numeric value above n.
*/
greaterThan(n: number): Assertion;

/**
* Assert numeric value above n.
*/
above(n: number): Assertion;

/**
* Assert numeric value below n.
*/
lessThan(n: number): Assertion;

/**
* Assert numeric value below n.
*/
below(n: number): Assertion;

/**
* Assert string value matches regexp.
*
* @param regexp
*/
match(regexp: RegExp): Assertion;

/**
* Assert property "length" exists and has value of n.
*
* @param n
*/
length(n: number): Assertion;

/**
* Assert property name exists, with optional val.
*
* @param name
* @param val
*/
property(name: string, val?: any): Assertion;

/**
* Assert that string contains str.
*/
contain(str: string): Assertion;
string(str: string): Assertion;

/**
* Assert that the array contains obj.
*/
contain(obj: any): Assertion;
string(obj: any): Assertion;

/**
* Assert exact keys or inclusion of keys by using the `.own` modifier.
*/
key(keys: string[]): Assertion;
/**
* Assert exact keys or inclusion of keys by using the `.own` modifier.
*/
key(...keys: string[]): Assertion;
/**
* Assert exact keys or inclusion of keys by using the `.own` modifier.
*/
keys(keys: string[]): Assertion;
/**
* Assert exact keys or inclusion of keys by using the `.own` modifier.
*/
keys(...keys: string[]): Assertion;

/**
* Assert a failure.
*/
fail(message?: string): Assertion;
}

interface Root extends Assertion {
not: Not;
to: To;
only: Only;
have: Have;
be: Be;
}

interface Be extends Assertion {
/**
* Checks if the obj exactly equals another.
*/
(obj: any): Assertion;

an: An;
}

interface An extends Assertion {
/**
* Assert typeof.
*/
(type: string): Assertion;

/**
* Assert instanceof.
*/
(type: Function): Assertion;
}

interface Not extends NotBase {
to: ToBase;
}

interface NotBase extends Assertion {
be: Be;
have: Have;
include: Assertion;
only: Only;
}

interface To extends ToBase {
not: NotBase;
}

interface ToBase extends Assertion {
be: Be;
have: Have;
include: Assertion;
only: Only;
}

interface Only extends Assertion {
have: Have;
}

interface Have extends Assertion {
own: Assertion;
}

export default expect;
}
80 changes: 80 additions & 0 deletions packages/kbn-test/types/ftr.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { DefaultServiceProviders } from '../../../src/functional_test_runner/types';

interface AsyncInstance<T> {
/**
* Services that are initialized async are not ready before the tests execute, so you might need
* to call `init()` and await the promise it returns before interacting with the service
*/
init(): Promise<T>;
}

/**
* When a provider returns a promise it is initialized as an AsyncInstance that is a
* proxy to the eventual result with an added init() method which returns the eventual
* result. Automatically unwrap these promises and convert them to AsyncInstances + Instance
* types.
*/
type MaybeAsyncInstance<T> = T extends Promise<infer X> ? AsyncInstance<X> & X : T;

/**
* Convert a map of providers to a map of the instance types they provide, also converting
* promise types into the async instances that other providers will receive.
*/
type ProvidedTypeMap<T extends object> = {
[K in keyof T]: T[K] extends (...args: any[]) => any
? MaybeAsyncInstance<ReturnType<T[K]>>
: never
};

export interface GenericFtrProviderContext<
ServiceProviders extends object,
PageObjectProviders extends object,
ServiceMap = ProvidedTypeMap<ServiceProviders & DefaultServiceProviders>,
PageObjectMap = ProvidedTypeMap<PageObjectProviders>
> {
/**
* Determine if a service is avaliable
* @param serviceName
*/
hasService<K extends keyof ServiceMap>(serviceName: K): serviceName is K;
hasService(serviceName: string): serviceName is keyof ServiceMap;

/**
* Get the instance of a service, if the service is loaded async and the service needs to be used
* outside of a test/hook, then make sure to call its `.init()` method and await it's promise.
* @param serviceName
*/
getService<T extends keyof ServiceMap>(serviceName: T): ServiceMap[T];

/**
* Get a map of PageObjects
* @param pageObjects
*/
getPageObjects<K extends keyof PageObjectMap>(pageObjects: K[]): Pick<PageObjectMap, K>;

/**
* Synchronously load a test file, can be called within a `describe()` block to add
* common setup/teardown steps to several suites
* @param path
*/
loadTestFile(path: string): void;
}
2 changes: 1 addition & 1 deletion src/dev/typescript/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ import { Project } from './project';

export const PROJECTS = [
new Project(resolve(REPO_ROOT, 'tsconfig.json')),
new Project(resolve(REPO_ROOT, 'test/tsconfig.json'), 'kibana/test'),
new Project(resolve(REPO_ROOT, 'x-pack/tsconfig.json')),
new Project(resolve(REPO_ROOT, 'x-pack/test/tsconfig.json'), 'x-pack/test'),
new Project(resolve(REPO_ROOT, 'test/tsconfig.json')),

// NOTE: using glob.sync rather than glob-all or globby
// because it takes less than 10 ms, while the other modules
Expand Down
Loading

0 comments on commit ba82d02

Please sign in to comment.