Added TypeScript type checker + Fixed type errors. (#5780)

* Added type_check.js

* Now checks cli, too.

* Ignored a line that should fail.

* Removed cli shims and post-install.

* Updated @types/chai to fix type error.

* Fixed keyboard type errors.

* Updated typescript to 3.7.2 to fix window.Node error in dom/document.

* Removed tsconfig errors that caused type errors in reporter and runner.

* Ignored error test by dtslint. Becaust it's done by type_check.js

* Added npm command.

* Added it to CI.

* Added skipLibCheck option.

* Removed checking chai folder existence.

copy of chai is unnecessary.

* Added 'ignore-progress' option for CI.

* Show success message when type check is finished successfully.

* Use ignore-progress option on CI.

* Moved type definitions from devDependencies to dependencies.

* Fixed new type errors after rebase.

* Updated type errors.

* Removed cli. Because its types are checked by dtslint.

* type_check -> type-check for consistency.

* Updated json-schema.

* Updated blob-util.

* Fix wrong command in CI.

* Revert "Updated blob-util."

This reverts commit e46549af54.
Because it's a breaking change.

* Remove copies of @types if exists.

* Fix stream buffer type error.

* Fix type errors in ui-components.

* Fix type failure.

* Fix lint error.

* Fix type errors

* Regenerate yarn.lock

* Fix type error.

* Fix type failures.

Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
Co-authored-by: Gleb Bahmutov <gleb.bahmutov@gmail.com>
This commit is contained in:
Kukhyeon Heo
2020-03-17 13:31:31 +09:00
committed by GitHub
parent 296c3b8b2b
commit ee494d04ee
31 changed files with 260 additions and 329 deletions

View File

@@ -318,11 +318,10 @@ jobs:
- run:
command: ls -la types
working_directory: cli
- run:
command: ls -la chai
working_directory: cli/types
- run:
command: yarn lerna exec --scope cypress "yarn dtslint"
- run:
command: yarn type-check --ignore-progress
- store-npm-logs
"server-unit-tests":

View File

@@ -22,6 +22,16 @@
"dependencies": {
"@cypress/listr-verbose-renderer": "0.4.1",
"@cypress/xvfb": "1.2.4",
"@types/blob-util": "1.3.3",
"@types/bluebird": "3.5.29",
"@types/chai": "4.2.7",
"@types/chai-jquery": "1.1.40",
"@types/jquery": "3.3.31",
"@types/lodash": "4.14.149",
"@types/minimatch": "3.0.3",
"@types/mocha": "5.2.7",
"@types/sinon": "7.5.1",
"@types/sinon-chai": "3.2.3",
"@types/sizzle": "2.3.2",
"arch": "2.1.1",
"bluebird": "3.7.2",
@@ -60,16 +70,6 @@
"devDependencies": {
"@cypress/sinon-chai": "1.1.0",
"@packages/root": "*",
"@types/blob-util": "1.3.3",
"@types/bluebird": "3.5.29",
"@types/chai": "4.2.7",
"@types/chai-jquery": "1.1.40",
"@types/jquery": "3.3.31",
"@types/lodash": "4.14.149",
"@types/minimatch": "3.0.3",
"@types/mocha": "5.2.7",
"@types/sinon": "7.5.1",
"@types/sinon-chai": "3.2.3",
"babel-cli": "6.26.0",
"babel-preset-es2015": "6.24.1",
"chai": "3.5.0",

View File

@@ -1,64 +1,28 @@
#!/usr/bin/env node
const fs = require('../lib/fs')
const path = require('path')
const { includeTypes } = require('./utils')
const shell = require('shelljs')
const { join } = require('path')
const resolvePkg = require('resolve-pkg')
/**
* https://github.com/cypress-io/cypress/pull/5780
* Folder names in "node_modules/@types" that were copied to cli/types to generate index.d.ts.
* They cause type errors in type checker. So, they should be removed.
*/
const includeTypes = [
'blob-util',
'bluebird',
'lodash',
'mocha',
'minimatch',
'sinon',
'sinon-chai',
'chai',
'chai-jquery',
'jquery',
]
shell.set('-v') // verbose
shell.set('-e') // any error is fatal
includeTypes.forEach((t) => {
const dir = path.join(__dirname, '../types', t)
// We include the TypeScript definitions for the bundled 3rd party tools
// thus we need to copy them from "dev" dependencies into our types folder
// and we need to sometimes tweak these types files to use relative paths
// This ensures that globals like Cypress.$, Cypress._ etc are property typed
// yet we do not install "@types/.." packages with "npm install cypress"
// because they can conflict with user's own libraries
includeTypes.forEach((folder) => {
const source = resolvePkg(`@types/${folder}`, { cwd: join(__dirname, '..', '..') })
shell.cp('-R', source, 'types')
if (fs.existsSync(dir)) {
fs.removeSync(dir)
}
})
// jQuery v3.3.x includes "dist" folder that just references back to itself
// causing dtslint to think there are double definitions. Remove that folder.
const typesJqueryDistFolder = join('types', 'jquery', 'dist')
shell.rm('-rf', typesJqueryDistFolder)
// fix paths to Chai, jQuery and other types to be relative
shell.sed(
'-i',
'<reference types="chai" />',
'<reference path="../chai/index.d.ts" />',
join('types', 'chai-jquery', 'index.d.ts'),
)
shell.sed(
'-i',
'<reference types="jquery" />',
'<reference path="../jquery/index.d.ts" />',
join('types', 'chai-jquery', 'index.d.ts'),
)
const sinonChaiFilename = join('types', 'sinon-chai', 'index.d.ts')
shell.sed(
'-i',
'<reference types="chai" />',
'<reference path="../chai/index.d.ts" />',
sinonChaiFilename,
)
// also use relative import via path for sinon-chai
// there is reference comment line we need to fix to be relative
shell.sed(
'-i',
'<reference types="sinon" />',
'<reference path="../sinon/index.d.ts" />',
sinonChaiFilename,
)
// and an import sinon line to be changed to relative path
shell.sed('-i', 'from \'sinon\';', 'from \'../sinon\';', sinonChaiFilename)

View File

@@ -1,7 +1,5 @@
#!/usr/bin/env node
const { includeTypes } = require('./utils')
const { join } = require('path')
const shell = require('shelljs')
shell.set('-v') // verbose
@@ -15,12 +13,6 @@ shell.cp('NPM_README.md', 'build/README.md')
shell.cp('.release.json', 'build/.release.json')
// copies our typescript definitions
shell.cp('-R', 'types/*.ts', 'build/types/')
// copies 3rd party typescript definitions
includeTypes.forEach((folder) => {
const source = join('types', folder)
shell.cp('-R', source, 'build/types')
})
shell.exec('babel lib -d build/lib')
shell.exec('babel index.js -o build/index.js')

View File

@@ -1,19 +0,0 @@
/**
* Folder names in "node_modules/@types" that we should include
* when we bundle Cypress NPM package. These folder have ".d.ts"
* definition files that we will need to include with our NPM package.
*/
const includeTypes = [
'blob-util',
'bluebird',
'lodash',
'mocha',
'minimatch',
'sinon',
'sinon-chai',
'chai',
'chai-jquery',
'jquery',
]
module.exports = { includeTypes }

View File

@@ -1,13 +0,0 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
// so that Cypress can get and use the Blob type
// tslint:disable-next-line:no-implicit-dependencies
import * as blobUtil from './blob-util'
export = BlobUtil
export as namespace BlobUtil
declare namespace BlobUtil {
type BlobUtilStatic = typeof blobUtil
}

View File

@@ -1,11 +0,0 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
// so that Cypress can get and use the Blob type
import BluebirdStatic = require('./bluebird')
export = Bluebird
export as namespace Bluebird
declare namespace Bluebird {
type BluebirdStatic = typeof BluebirdStatic
}

View File

@@ -1,10 +0,0 @@
// Shim definition to export a namespace. Cypress is actually a global module
// so import/export isn't allowed there. We import here and define a global module
/// <reference path="./chai/index.d.ts" />
declare namespace Chai {
interface Include {
html(html: string): Assertion
text(text: string): Assertion
value(text: string): Assertion
}
}

View File

@@ -1,96 +0,0 @@
// I was trying to avoid relying on "import" of actual module from "minimatch"
// because it would not work in test project, and the only reliable way
// to get around type errors finally was to copy the minimal minimatch function
// definition from "minimatch/index.d.ts" here and just keep it in our code
export = Minimatch
export as namespace Minimatch
interface MinimatchOptions {
/**
* Dump a ton of stuff to stderr.
*
* @default false
*/
debug?: boolean
/**
* Do not expand {a,b} and {1..3} brace sets.
*
* @default false
*/
nobrace?: boolean
/**
* Disable ** matching against multiple folder names.
*
* @default false
*/
noglobstar?: boolean
/**
* Allow patterns to match filenames starting with a period,
* even if the pattern does not explicitly have a period in that spot.
*
* @default false
*/
dot?: boolean
/**
* Disable "extglob" style patterns like +(a|b).
*
* @default false
*/
noext?: boolean
/**
* Perform a case-insensitive match.
*
* @default false
*/
nocase?: boolean
/**
* When a match is not found by minimatch.match,
* return a list containing the pattern itself if this option is set.
* Otherwise, an empty list is returned if there are no matches.
*
* @default false
*/
nonull?: boolean
/**
* If set, then patterns without slashes will be matched against
* the basename of the path if it contains slashes.
*
* @default false
*/
matchBase?: boolean
/**
* Suppress the behavior of treating #
* at the start of a pattern as a comment.
*
* @default false
*/
nocomment?: boolean
/**
* Suppress the behavior of treating a leading ! character as negation.
*
* @default false
*/
nonegate?: boolean
/**
* Returns from negate expressions the same as if they were not negated.
* (Ie, true on a hit, false on a miss.)
*
* @default false
*/
flipNegate?: boolean
}
declare namespace Minimatch {
function minimatch(target: string, pattern: string, options?: MinimatchOptions): boolean
}

View File

@@ -1,7 +0,0 @@
import moment = require('moment')
export = Moment
export as namespace Moment
declare namespace Moment {
type MomentStatic = typeof moment
}

45
cli/types/index.d.ts vendored
View File

@@ -4,47 +4,52 @@
// Mike Woudenberg <https://github.com/mikewoudenberg>
// Robbert van Markus <https://github.com/rvanmarkus>
// Nicholas Boll <https://github.com/nicholasboll>
// TypeScript Version: 2.9
// TypeScript Version: 3.0
// Updated by the Cypress team: https://www.cypress.io/about/
/// <reference path="./cy-blob-util.d.ts" />
/// <reference path="./cy-bluebird.d.ts" />
/// <reference path="./cy-moment.d.ts" />
/// <reference path="./cy-minimatch.d.ts" />
/// <reference path="./cy-chai.d.ts" />
/// <reference path="./lodash/index.d.ts" />
/// <reference path="./sinon/index.d.ts" />
/// <reference path="./sinon-chai/index.d.ts" />
/// <reference path="./mocha/index.d.ts" />
/// <reference path="./jquery/index.d.ts" />
/// <reference path="./chai-jquery/index.d.ts" />
/// <reference types="blob-util" />
/// <reference types="lodash" />
/// <reference types="sinon" />
/// <reference types="sinon-chai" />
/// <reference types="mocha" />
/// <reference types="jquery" />
/// <reference types="chai" />
/// <reference types="chai-jquery" />
/// <reference types="bluebird" />
// jQuery includes dependency "sizzle" that provides types
// so we include it too in "node_modules/sizzle".
// This way jQuery can load it using 'reference types="sizzle"' directive
// "moment" types are with "node_modules/moment"
/// <reference types="moment" />
// load ambient declaration for "cypress" NPM module
// hmm, how to load it better?
/// <reference path="./cypress-npm-api.d.ts" />
// Cypress, cy, Log inherits EventEmitter.
type EventEmitter2 = import("eventemitter2").EventEmitter2
type Bluebird<R> = import("bluebird")<R>
type Nullable<T> = T | null
interface EventEmitter extends EventEmitter2 {
proxyTo: (cy: Cypress.cy) => null
emitMap: (eventName: string, args: any[]) => Array<(...args: any[]) => any>
emitThen: (eventName: string, args: any[]) => Bluebird.BluebirdStatic
emitThen: (eventName: string, args: any[]) => Bluebird<any>
}
// Cypress adds chai expect and assert to global
declare const expect: Chai.ExpectStatic
declare const assert: Chai.AssertStatic
// Cypress extension of chai
declare namespace Chai {
interface Include {
html(html: string): Assertion
text(text: string): Assertion
value(text: string): Assertion
}
}
declare namespace Cypress {
type FileContents = string | any[] | object
type HistoryDirection = "back" | "forward"
@@ -182,13 +187,13 @@ declare namespace Cypress {
* @example
* Cypress.Blob.method()
*/
Blob: BlobUtil.BlobUtilStatic
Blob: typeof import('blob-util')
/**
* Cypress automatically includes minimatch and exposes it as Cypress.minimatch.
*
* @see https://on.cypress.io/minimatch
*/
minimatch: typeof Minimatch.minimatch
minimatch: typeof import('minimatch')
/**
* Cypress automatically includes moment.js and exposes it as Cypress.moment.
*
@@ -197,7 +202,7 @@ declare namespace Cypress {
* @example
* const todaysDate = Cypress.moment().format("MMM DD, YYYY")
*/
moment: Moment.MomentStatic
moment: typeof import('moment')
/**
* Cypress automatically includes Bluebird and exposes it as Cypress.Promise.
*
@@ -206,7 +211,7 @@ declare namespace Cypress {
* @example
* new Cypress.Promise((resolve, reject) => { ... })
*/
Promise: Bluebird.BluebirdStatic
Promise: typeof import('bluebird')
/**
* Cypress includes Sinon.js library used in `cy.spy` and `cy.stub`.
*

View File

@@ -66,6 +66,7 @@
"test-unit": "lerna exec yarn test-unit --ignore \"'@packages/{coffee,desktop-gui,driver,root,static,web-config}'\"",
"pretest-watch": "yarn ensure-deps",
"test-watch": "lerna exec yarn test-watch --ignore \"'@packages/{coffee,desktop-gui,driver,root,static,web-config}'\"",
"type-check": "node scripts/type_check",
"verify:mocha:results": "node ./scripts/verify_mocha_results",
"prewatch": "yarn ensure-deps",
"watch": "lerna exec yarn watch --parallel --stream"
@@ -88,6 +89,8 @@
"@types/chai-enzyme": "0.6.7",
"@types/classnames": "2.2.9",
"@types/debug": "4.1.5",
"@types/enzyme": "3.9.1",
"@types/enzyme-adapter-react-16": "1.0.5",
"@types/execa": "0.9.0",
"@types/fs-extra": "8.0.1",
"@types/glob": "7.1.1",
@@ -96,7 +99,8 @@
"@types/mini-css-extract-plugin": "0.8.0",
"@types/mocha": "5.2.7",
"@types/node": "12.12.21",
"@types/ramda": "0.26.38",
"@types/ramda": "0.25.47",
"@types/react": "16.9.23",
"@types/react-dom": "16.9.4",
"@types/request-promise": "4.1.45",
"@types/sinon-chai": "3.2.3",
@@ -121,6 +125,7 @@
"decaffeinate": "6.0.9",
"del": "3.0.0",
"electron-builder": "20.39.0",
"enzyme-adapter-react-16": "1.12.1",
"eslint": "6.8.0",
"eslint-plugin-cypress": "2.10.3",
"eslint-plugin-json-format": "2.0.0",
@@ -150,6 +155,7 @@
"lazy-ass": "1.6.0",
"lerna": "3.18.3",
"lint-staged": "9.4.1",
"listr": "0.14.3",
"lodash": "4.17.15",
"make-empty-github-commit": "1.2.0",
"mocha": "3.5.3",

View File

@@ -7,6 +7,8 @@ import { USKeyboard } from '../cypress/UsKeyboardLayout'
import * as $dom from '../dom'
import * as $document from '../dom/document'
import * as $elements from '../dom/elements'
// eslint-disable-next-line no-duplicate-imports
import { HTMLTextLikeElement, HTMLTextLikeInputElement } from '../dom/elements'
import * as $selection from '../dom/selection'
import $window from '../dom/window'
@@ -583,6 +585,7 @@ const keyToModifierMap = {
}
export interface typeOptions {
id: string
$el: JQuery
chars: string
force?: boolean
@@ -601,7 +604,6 @@ export interface typeOptions {
onNoMatchingSpecialChars?: Function
onBeforeSpecialCharAction?: Function
prevValue?: string
id?: string
}
export class Keyboard {
@@ -735,7 +737,7 @@ export class Keyboard {
// simulatedDefaultOnly keys will not send any events, and cannot be canceled
if (key.simulatedDefaultOnly) {
key.simulatedDefault!(activeEl, key, options)
key.simulatedDefault!(activeEl as HTMLTextLikeElement, key, options)
return null
}
@@ -1124,7 +1126,7 @@ export class Keyboard {
return
}
return simulatedDefault(el, key, options)
return simulatedDefault(el as HTMLTextLikeElement, key, options)
}
}

View File

@@ -644,7 +644,7 @@ const isAttached = function ($el) {
// is technically bound to a different document
// but c'mon
const isIn = (el) => {
return $.contains(doc, el)
return $.contains(doc as any, el)
}
// make sure the document is currently

View File

@@ -21,7 +21,6 @@
"@packages/socket": "*",
"@packages/web-config": "*",
"@types/chai-enzyme": "0.6.7",
"@types/enzyme": "3.10.4",
"chai": "3.5.0",
"chai-enzyme": "1.0.0-beta.1",
"classnames": "2.2.6",

View File

@@ -98,12 +98,16 @@ const Aliases = observer(({ model, aliasesWithDuplicates }: AliasesProps) => {
)
})
const Message = observer(({ model }) => (
interface MessageProps {
model: CommandModel
}
const Message = observer(({ model }: MessageProps) => (
<span>
<i className={`fas fa-circle ${model.renderProps.indicator}`}></i>
<span
className='command-message-text'
dangerouslySetInnerHTML={{ __html: formattedMessage(model.displayMessage) }}
dangerouslySetInnerHTML={{ __html: formattedMessage(model.displayMessage || '') }}
/>
</span>
))

1
packages/reporter/src/global.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
declare const expect: Chai.ExpectStatic

View File

@@ -1,4 +1,4 @@
import React from 'react'
import React, { ReactElement } from 'react'
import { shallow } from 'enzyme'
import sinon, { SinonSpy } from 'sinon'
@@ -24,7 +24,7 @@ describe('<Header />', () => {
it('renders a tooltip around focus tests button', () => {
const title = shallow(<Header appState={appState} statsStore={statsStore} />)
.find('Tooltip')
.prop('title')
.prop<ReactElement>('title')
const component = shallow(title)

View File

@@ -1,4 +1,5 @@
import sinon from 'sinon'
import Hook from './hook-model'
import CommandModel from '../commands/command-model'

View File

@@ -129,7 +129,7 @@ export class Scroller {
this._container = null
this._userScroll = true
this._userScrollCount = 0
clearTimeout(this._countUserScrollsTimeout)
clearTimeout(this._countUserScrollsTimeout as TimeoutID)
this._countUserScrollsTimeout = undefined
}
}

View File

@@ -26,6 +26,8 @@ interface Props {
export type LogProps = AgentProps | CommandProps | RouteProps
export type RunnableArray = Array<TestModel | SuiteModel>
type Log = AgentModel | CommandModel | RouteModel
export interface RootRunnable {
@@ -38,7 +40,7 @@ type TestOrSuite<T> = T extends TestProps ? TestProps : SuiteProps
class RunnablesStore {
@observable isReady = defaults.isReady
@observable runnables: Array<TestModel | SuiteModel> = []
@observable runnables: RunnableArray = []
hasTests: boolean = false
hasSingleTest: boolean = false

View File

@@ -128,7 +128,7 @@ describe('<Runnables />', () => {
context('<RunnablesList />', () => {
it('renders a runnable for each runnable in model', () => {
const component = shallow(<RunnablesList runnables={[{ id: 1 }, { id: 2 }]} />)
const component = shallow(<RunnablesList runnables={[{ id: 1 } as TestModel, { id: 2 } as TestModel]} />)
expect(component.find('Runnable').length).to.equal(2)
})

View File

@@ -5,7 +5,7 @@ import React, { Component } from 'react'
import AnError, { Error } from '../errors/an-error'
import Runnable from './runnable-and-suite'
import { RunnablesStore } from './runnables-store'
import { RunnablesStore, RunnableArray } from './runnables-store'
import { Scroller } from '../lib/scroller'
import { AppState } from '../lib/app-state'
@@ -16,7 +16,11 @@ const noTestsError = (specPath: string) => ({
message: 'We could not detect any tests in the above file. Write some tests and re-run.',
})
const RunnablesList = observer(({ runnables }) => (
interface RunnablesListProps {
runnables: RunnableArray
}
const RunnablesList = observer(({ runnables }: RunnablesListProps) => (
<div className='wrap'>
<ul className='runnables'>
{_.map(runnables, (runnable) => <Runnable key={runnable.id} model={runnable} />)}

View File

@@ -9,6 +9,7 @@
*/
"allowJs": true,
"jsx": "react",
"outDir": "dist",
"noImplicitAny": true,
"noImplicitThis": true,
"preserveWatchOutput": true,
@@ -45,12 +46,6 @@
// "baseUrl": "../", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": ["../driver/src"], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": [
"../driver/node_modules",
"../../cli/types/index.d.ts",
"../driver/src",
"./node_modules"
], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,

View File

@@ -21,8 +21,6 @@
"@packages/reporter": "*",
"@packages/socket": "*",
"@packages/web-config": "*",
"@types/enzyme": "3.10.4",
"@types/react": "16.9.21",
"ansi-to-html": "0.6.14",
"bluebird": "3.5.0",
"chai": "4.2.0",

View File

@@ -9,6 +9,7 @@
*/
"allowJs": true,
"jsx": "react",
"outDir": "dist",
"noImplicitAny": false,
"noImplicitThis": false,
"preserveWatchOutput": true,
@@ -45,12 +46,6 @@
// "baseUrl": "../", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": ["../driver/src"], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": [
"../driver/node_modules",
"../../cli",
"../driver/src",
"./node_modules",
], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,

View File

@@ -45,12 +45,6 @@
// "baseUrl": "../", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": ["../driver/src"], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": [
"../driver/node_modules",
"../../cli/types/index.d.ts",
"../driver/src",
"./node_modules"
], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,

View File

@@ -1,6 +1,9 @@
import mockRequire from 'mock-require'
import { JSDOM } from 'jsdom'
import * as ansiEscapes from 'ansi-escapes'
import enzyme from 'enzyme'
import EnzymeAdapter from 'enzyme-adapter-react-16'
import ChaiEnzyme from 'chai-enzyme'
declare global {
module NodeJS {
@@ -10,12 +13,21 @@ declare global {
}
}
interface RegisterDeps {
enzyme: typeof enzyme
EnzymeAdapter: typeof EnzymeAdapter
chaiEnzyme: typeof ChaiEnzyme
requireOverride: (...args: any[]) => any
}
type TimeoutID = number
export const register = ({
enzyme,
EnzymeAdapter,
chaiEnzyme,
requireOverride,
}) => {
}: RegisterDeps) => {
const jsdom = new JSDOM('<!doctype html><html><body></body></html>')
const { window } = jsdom
@@ -24,28 +36,31 @@ export const register = ({
// const chaiEnzyme = require('chai-enzyme')
global.window = window
global.document = window.document
window.Selection = { prototype: { isCollapsed: {} } }
global.document = window.document;
// DOMWindow doesn't have Selection yet.
(window as any).Selection = { prototype: { isCollapsed: {} } }
global.navigator = {
userAgent: 'node.js',
}
global.requestAnimationFrame = function (callback) {
global.requestAnimationFrame = function (callback: ((...args: any[]) => void)) {
return setTimeout(callback, 0)
}
global.cancelAnimationFrame = function (id) {
global.cancelAnimationFrame = function (id: TimeoutID) {
clearTimeout(id)
}
Object.keys(window.document.defaultView).forEach((property) => {
Object.keys(window.document.defaultView as Record<string, any>).forEach((property) => {
if (
property === 'localStorage' ||
property === 'sessionStorage' ||
typeof global[property] !== 'undefined'
) return
global[property] = window.document.defaultView[property]
global[property] = (window.document.defaultView as Record<string, any>)[property]
})
// enzyme, and therefore chai-enzyme, needs to be required after
@@ -63,7 +78,7 @@ export const register = ({
const overrideRequire = () => {
const _load = Module._load
Module._load = function (...args) {
Module._load = function (...args: any[]) {
let browserPkg = args
if (requireOverride) {
@@ -107,7 +122,7 @@ after(() => {
process.stdout.write(ansiEscapes.cursorShow)
})
export const returnMockRequire = (name, modExport = {}) => {
export const returnMockRequire = (name: string, modExport: object = {}) => {
mockRequire(name, modExport)
return require(name)

View File

@@ -13,6 +13,8 @@
"@packages/coffee": "*",
"@types/copy-webpack-plugin": "5.0.0",
"@types/html-webpack-plugin": "3.2.1",
"@types/jsdom": "^12.2.4",
"@types/mock-require": "^2.0.0",
"@types/webpack": "4.41.0",
"ansi-escapes": "4.3.0",
"autoprefixer": "9.7.4",

93
scripts/type_check.js Normal file
View File

@@ -0,0 +1,93 @@
const fs = require('fs')
const path = require('path')
const execa = require('execa')
const Listr = require('listr')
const commander = require('commander')
const program = new commander.Command()
program.usage('[options]')
program
.option('-p, --project <projects>', 'projects to check types (separated by commas)')
.option('--skip-lib-check', 'skip type checking of all declaration files (*.d.ts)')
.option('--ignore-progress', 'do not show progress')
.action((...args) => {
const projects = []
const packageRoot = path.join(__dirname, '../packages')
const getPackagePath = (name) => {
if (name !== 'cli') {
return path.join(packageRoot, name)
}
throw new Error(`type-check command doesn't check cli types. Use "npm run dtslint" in "cli" directory instead.`)
}
const addProject = (name) => {
return projects.push({
name,
path: getPackagePath(name),
})
}
if (program.project) {
program.project.split(',').forEach((p) => addProject(p))
} else {
fs.readdirSync(packageRoot).forEach((file) => {
const packagePath = getPackagePath(file)
if (fs.lstatSync(packagePath).isDirectory() && fs.existsSync(path.join(packagePath, 'tsconfig.json'))) {
addProject(file)
}
})
}
const options = ['--noEmit', '--pretty']
if (program.skipLibCheck) {
options.push('--skipLibCheck')
}
const tasks = new Listr(projects.map((proj) => {
return {
title: proj.name,
task: () => {
const cwd = proj.path
const tsc = require.resolve('typescript/bin/tsc')
return execa(tsc, options, {
cwd,
}).catch((err) => {
throw {
name: proj.name,
err,
}
})
},
}
}), {
concurrent: 4,
exitOnError: false,
renderer: program.ignoreProgress ? 'silent' : 'default',
})
tasks.run()
.then(() => {
log('')
log('Type check passed successfully.')
})
.catch((err) => {
process.exitCode = 1
err.errors.forEach((e) => {
log('')
log(`${e.name} failed\n${e.err.stdout}`)
})
})
})
const log = (msg) => {
// eslint-disable-next-line no-console
console.log(msg)
}
program.parse(process.argv)

View File

@@ -3477,6 +3477,13 @@
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==
"@types/enzyme-adapter-react-16@1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.0.5.tgz#1bf30a166f49be69eeda4b81e3f24113c8b4e9d5"
integrity sha512-K7HLFTkBDN5RyRmU90JuYt8OWEY2iKUn43SDWEoBOXd/PowUWjLZ3Q6qMBiQuZeFYK/TOstaZxsnI0fXoAfLpg==
dependencies:
"@types/enzyme" "*"
"@types/enzyme@*":
version "3.10.5"
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.5.tgz#fe7eeba3550369eed20e7fb565bfb74eec44f1f0"
@@ -3485,10 +3492,10 @@
"@types/cheerio" "*"
"@types/react" "*"
"@types/enzyme@3.10.4":
version "3.10.4"
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.10.4.tgz#dd4961042381a7c0f6637ce25fec3f773ce489dd"
integrity sha512-P5XpxcIt9KK8QUH4al4ttfJfIHg6xmN9ZjyUzRSzAsmDYwRXLI05ng/flZOPXrEXmp8ZYiN8/tEXYK5KSOQk3w==
"@types/enzyme@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@types/enzyme/-/enzyme-3.9.1.tgz#3a0ce07e30066dbc26cd3474c8e680af2d249e26"
integrity sha512-CasnOP73BFE3/5JvGkod+oQtGOD1+CVWz9BV2iAqDFJ+sofL5gTiizSr8ZM3lpDY27ptC8yjAdrUCdv8diKKqw==
dependencies:
"@types/cheerio" "*"
"@types/react" "*"
@@ -3607,6 +3614,15 @@
dependencies:
"@types/sizzle" "*"
"@types/jsdom@^12.2.4":
version "12.2.4"
resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-12.2.4.tgz#845cd4d43f95b8406d9b724ec30c03edadcd9528"
integrity sha512-q+De3S/Ri6U9uPx89YA1XuC+QIBgndIfvBaaJG0pRT8Oqa75k4Mr7G9CRZjIvlbLGIukO/31DFGFJYlQBmXf/A==
dependencies:
"@types/node" "*"
"@types/tough-cookie" "*"
parse5 "^4.0.0"
"@types/json-schema@^7.0.3":
version "7.0.4"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339"
@@ -3661,6 +3677,13 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea"
integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==
"@types/mock-require@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/mock-require/-/mock-require-2.0.0.tgz#57a4f0db0b4b6274f610a2d2c20beb3c842181e1"
integrity sha512-nOgjoE5bBiDeiA+z41i95makyHUSMWQMOPocP+J67Pqx/68HAXaeWN1NFtrAYYV6LrISIZZ8vKHm/a50k0f6Sg==
dependencies:
"@types/node" "*"
"@types/node@*", "@types/node@>= 8":
version "13.9.1"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.1.tgz#96f606f8cd67fb018847d9b61e93997dabdefc72"
@@ -3711,13 +3734,6 @@
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.25.47.tgz#904f2ee46149af42902fe7dc01867e32798e8b37"
integrity sha512-+ffSU83+PR4/cZtNTkUcFkg70sK4GePle7p5h05bQ37ycPumOx/TBpU52bt36GKDlds6tCqXheqPvgC52MMLug==
"@types/ramda@0.26.38":
version "0.26.38"
resolved "https://registry.yarnpkg.com/@types/ramda/-/ramda-0.26.38.tgz#9d19bb910bb15fc9a213402092e160cbbb5acc9b"
integrity sha512-legQx15y72vedr5fkVTb5xZaI/OXMzJgZYbMxVL5r269sOg7fZIeitEOumcevMPOMZdqH4cMoL35VuU13TLvVA==
dependencies:
ts-toolbelt "^4.12.0"
"@types/range-parser@*":
version "1.2.3"
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
@@ -3730,7 +3746,7 @@
dependencies:
"@types/react" "*"
"@types/react@*":
"@types/react@*", "@types/react@16.9.23":
version "16.9.23"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c"
integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw==
@@ -3738,14 +3754,6 @@
"@types/prop-types" "*"
csstype "^2.2.0"
"@types/react@16.9.21":
version "16.9.21"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.21.tgz#99e274e2ecfab6bb93920e918341daa3198b348d"
integrity sha512-xpmenCMeBwJRct8vmIfczlgdOXWIWASoOM857kxKfHlVQvDltRh7IFRVfGws79iO2jkNPXOeWREyKoClzhBaQA==
dependencies:
"@types/prop-types" "*"
csstype "^2.2.0"
"@types/relateurl@*":
version "0.2.28"
resolved "https://registry.yarnpkg.com/@types/relateurl/-/relateurl-0.2.28.tgz#6bda7db8653fa62643f5ee69e9f69c11a392e3a6"
@@ -10032,6 +10040,19 @@ env-variable@0.0.x:
resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.6.tgz#74ab20b3786c545b62b4a4813ab8cf22726c9808"
integrity sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==
enzyme-adapter-react-16@1.12.1:
version "1.12.1"
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.12.1.tgz#6a2d74c80559d35ac0a91ca162fa45f4186290cf"
integrity sha512-GB61gvY97XvrA6qljExGY+lgI6BBwz+ASLaRKct9VQ3ozu0EraqcNn3CcrUckSGIqFGa1+CxO5gj5is5t3lwrw==
dependencies:
enzyme-adapter-utils "^1.11.0"
object.assign "^4.1.0"
object.values "^1.1.0"
prop-types "^15.7.2"
react-is "^16.8.6"
react-test-renderer "^16.0.0-0"
semver "^5.6.0"
enzyme-adapter-react-16@1.15.2:
version "1.15.2"
resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.2.tgz#b16db2f0ea424d58a808f9df86ab6212895a4501"
@@ -10047,7 +10068,7 @@ enzyme-adapter-react-16@1.15.2:
react-test-renderer "^16.0.0-0"
semver "^5.7.0"
enzyme-adapter-utils@^1.13.0:
enzyme-adapter-utils@^1.11.0, enzyme-adapter-utils@^1.13.0:
version "1.13.0"
resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.0.tgz#01c885dde2114b4690bf741f8dc94cee3060eb78"
integrity sha512-YuEtfQp76Lj5TG1NvtP2eGJnFKogk/zT70fyYHXK2j3v6CtuHqc8YmgH/vaiBfL8K1SgVVbQXtTcgQZFwzTVyQ==
@@ -17995,7 +18016,7 @@ object.reduce@^1.0.0:
for-own "^1.0.0"
make-iterator "^1.0.0"
object.values@^1.1.1:
object.values@^1.1.0, object.values@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e"
integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==
@@ -18531,7 +18552,7 @@ parse-url@^5.0.0:
parse-path "^4.0.0"
protocols "^1.4.0"
parse5@4.0.0:
parse5@4.0.0, parse5@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608"
integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==
@@ -23284,11 +23305,6 @@ ts-node@8.3.0:
source-map-support "^0.5.6"
yn "^3.0.0"
ts-toolbelt@^4.12.0:
version "4.14.6"
resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-4.14.6.tgz#9a232f62276caeee4fa9e81e0c4bffa047de0765"
integrity sha512-SONcnRd93+LuYGfn/CZg5A5qhCODohZslAVZKHHu5bnwUxoXLqd2k2VIdwRUXYfKnY+UCeNbI2pTPz+Dno6Mpg==
tslib@^1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"