From e4a3bcc9d66e69468e0b926389d904b046315e0e Mon Sep 17 00:00:00 2001 From: Jason Staten Date: Tue, 10 Dec 2019 11:09:17 -0700 Subject: [PATCH] feat(build): TypeScript BREAKING CHANGE: fireEvent no longer causes a digest. The behavior is inconsistent with what the browser actually does BREAKING CHANGE: only a CommonJS distribution is built. TypeScript used for build, tests, and eslint parser --- .eslintrc.js | 7 +- .gitignore | 1 + babel.config.js | 1 + package.json | 47 ++++---- rollup.config.js | 22 ---- .../{render.js.snap => render.ts.snap} | 0 ...o-cleanup-skip.js => auto-cleanup-skip.ts} | 2 +- .../{auto-cleanup.js => auto-cleanup.ts} | 0 src/__tests__/{cleanup.js => cleanup.ts} | 2 +- src/__tests__/{debug.js => debug.ts} | 4 +- src/__tests__/digest.js | 39 ------ .../{end-to-end.js => end-to-end.ts} | 18 +-- src/__tests__/{events.js => events.ts} | 12 +- .../{multi-base.js => multi-base.ts} | 7 +- src/__tests__/{render.js => render.ts} | 4 +- src/__tests__/{stopwatch.js => stopwatch.ts} | 11 +- src/{index.js => index.ts} | 2 + src/{pure.js => pure.ts} | 112 +++++++++++------- tests/setup-env.js | 1 - tsconfig.json | 78 ++++++++++++ 20 files changed, 218 insertions(+), 152 deletions(-) delete mode 100644 rollup.config.js rename src/__tests__/__snapshots__/{render.js.snap => render.ts.snap} (100%) rename src/__tests__/{auto-cleanup-skip.js => auto-cleanup-skip.ts} (92%) rename src/__tests__/{auto-cleanup.js => auto-cleanup.ts} (100%) rename src/__tests__/{cleanup.js => cleanup.ts} (95%) rename src/__tests__/{debug.js => debug.ts} (93%) delete mode 100644 src/__tests__/digest.js rename src/__tests__/{end-to-end.js => end-to-end.ts} (83%) rename src/__tests__/{events.js => events.ts} (93%) rename src/__tests__/{multi-base.js => multi-base.ts} (86%) rename src/__tests__/{render.js => render.ts} (93%) rename src/__tests__/{stopwatch.js => stopwatch.ts} (86%) rename src/{index.js => index.ts} (90%) rename src/{pure.js => pure.ts} (56%) delete mode 100644 tests/setup-env.js create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index b397eaf..e278136 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,10 @@ module.exports = { jest: true, }, extends: ['eslint:recommended'], - parser: 'babel-eslint', + parser: '@typescript-eslint/parser', + parserOptions: { + sourceType: 'module', + }, rules: { 'linebreak-style': ['error', 'unix'], 'no-console': ['error', {allow: ['warn', 'error']}], @@ -17,5 +20,7 @@ module.exports = { 'object-shorthand': 'error', 'no-useless-rename': 'error', 'no-use-before-define': ['error', {functions: false}], + 'no-unused-vars': 'off', + 'no-duplicate-imports': 'off', }, } diff --git a/.gitignore b/.gitignore index 7ac65ac..88e049d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ lib .opt-out .DS_Store .eslintcache +.vscode yarn-error.log diff --git a/babel.config.js b/babel.config.js index 55b3e29..65d080c 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,4 +1,5 @@ module.exports = { + presets: ['@babel/preset-typescript'], env: { test: { plugins: [ diff --git a/package.json b/package.json index 6ec79cc..a56cb07 100644 --- a/package.json +++ b/package.json @@ -3,19 +3,18 @@ "version": "0.0.0-semantic-release", "description": "Simple and complete AngularJS testing utilities that encourage good testing practices.", "main": "lib/index.js", - "module": "lib/angularjs-testing-library.mjs", "engines": { "node": ">=10" }, "scripts": { "prebuild": "rimraf lib", - "build": "rollup -c", - "lint": "eslint --cache .", + "build": "tsc --noEmit false", + "lint": "eslint --ext .ts,.js --cache .", "test": "jest", "validate": "concurrently yarn:validate:*", - "validate:lnt": "yarn --silent lint", - "validate:bld": "yarn --silent build", - "validate:tst": "yarn --silent test" + "validate:lint": "yarn --silent lint", + "validate:build": "yarn --silent build", + "validate:test": "yarn --silent test" }, "husky": { "hooks": { @@ -25,7 +24,12 @@ "lint-staged": { "*.{js}": [ "prettier --write", - "eslint", + "eslint --fix", + "git add" + ], + "*.{ts}": [ + "prettier --write", + "eslint --fix", "git add" ], "*.{json,css,md}": [ @@ -36,13 +40,8 @@ "doctoc --maxlevel 3 --notitle" ] }, - "jest": { - "setupFilesAfterEnv": [ - "@testing-library/jest-dom/extend-expect" - ] - }, "files": [ - "lib", + "lib/*.{js,ts}", "dont-cleanup-after-each.js" ], "keywords": [ @@ -66,24 +65,26 @@ "@testing-library/dom": "^6.3.0" }, "devDependencies": { - "@babel/core": "^7.7.5", - "@babel/plugin-proposal-class-properties": "^7.7.4", - "@babel/plugin-transform-modules-commonjs": "^7.7.5", "@semantic-release/git": "^7.0.17", "@testing-library/jest-dom": "^4.1.0", + "@types/angular": "^1.6.57", + "@types/angular-mocks": "^1.7.0", + "@types/jest": "^24.0.23", + "@types/node": "^12.12.16", + "@typescript-eslint/parser": "^2.11.0", "angular": "^1.7.8", "angular-mocks": "^1.7.8", - "babel-eslint": "^10.0.3", - "babel-jest": "^24.9.0", "concurrently": "^5.0.0", "doctoc": "^1.4.0", "eslint": "^6.7.2", "husky": "^3.1.0", + "jest": "^24.9.0", "jest-cli": "^24.9.0", "lint-staged": "^9.5.0", "rimraf": "^3.0.0", - "rollup": "^1.27.8", - "semantic-release": "^15.13.30" + "semantic-release": "^15.13.30", + "ts-jest": "^24.2.0", + "typescript": "^3.7.3" }, "peerDependencies": { "angular": "*", @@ -117,5 +118,11 @@ ] ], "repositoryUrl": "git@git.sr.ht:~statianzo/angularjs-testing-library" + }, + "jest": { + "preset": "ts-jest", + "setupFilesAfterEnv": [ + "@testing-library/jest-dom/extend-expect" + ] } } diff --git a/rollup.config.js b/rollup.config.js deleted file mode 100644 index 7c57dee..0000000 --- a/rollup.config.js +++ /dev/null @@ -1,22 +0,0 @@ -import * as pkg from './package.json' - -const pkgDependencies = Object.keys({ - ...pkg.dependencies, - ...pkg.devDependencies, - ...pkg.peerDependencies, - ...pkg.optionalDependencies, -}) - -export default { - input: 'src/index', - output: [ - { - file: pkg.main, - format: 'cjs', - sourcemap: true, - externalLiveBindings: false, - }, - {file: pkg.module, format: 'es', sourcemap: true}, - ], - external: [...pkgDependencies], -} diff --git a/src/__tests__/__snapshots__/render.js.snap b/src/__tests__/__snapshots__/render.ts.snap similarity index 100% rename from src/__tests__/__snapshots__/render.js.snap rename to src/__tests__/__snapshots__/render.ts.snap diff --git a/src/__tests__/auto-cleanup-skip.js b/src/__tests__/auto-cleanup-skip.ts similarity index 92% rename from src/__tests__/auto-cleanup-skip.js rename to src/__tests__/auto-cleanup-skip.ts index 9c1963e..26f76b9 100644 --- a/src/__tests__/auto-cleanup-skip.js +++ b/src/__tests__/auto-cleanup-skip.ts @@ -1,4 +1,4 @@ -let render +let render: (html: string) => void beforeAll(() => { process.env.ATL_SKIP_AUTO_CLEANUP = 'true' const atl = require('../') diff --git a/src/__tests__/auto-cleanup.js b/src/__tests__/auto-cleanup.ts similarity index 100% rename from src/__tests__/auto-cleanup.js rename to src/__tests__/auto-cleanup.ts diff --git a/src/__tests__/cleanup.js b/src/__tests__/cleanup.ts similarity index 95% rename from src/__tests__/cleanup.js rename to src/__tests__/cleanup.ts index f061168..408e411 100644 --- a/src/__tests__/cleanup.js +++ b/src/__tests__/cleanup.ts @@ -1,4 +1,4 @@ -import angular from 'angular' +import * as angular from 'angular' import 'angular-mocks' import {render, cleanup} from '../' diff --git a/src/__tests__/debug.js b/src/__tests__/debug.ts similarity index 93% rename from src/__tests__/debug.js rename to src/__tests__/debug.ts index aa2b2ae..54dc332 100644 --- a/src/__tests__/debug.js +++ b/src/__tests__/debug.ts @@ -1,4 +1,4 @@ -import angular from 'angular' +import * as angular from 'angular' import 'angular-mocks' import {render} from '../' @@ -7,7 +7,7 @@ beforeEach(() => { }) afterEach(() => { - console.log.mockRestore() + (console.log as jest.Mock).mockRestore() }) beforeEach(() => { diff --git a/src/__tests__/digest.js b/src/__tests__/digest.js deleted file mode 100644 index 3b3e793..0000000 --- a/src/__tests__/digest.js +++ /dev/null @@ -1,39 +0,0 @@ -import angular from 'angular' -import 'angular-mocks' -import {render, fireEvent} from '../' - -beforeEach(() => { - angular.module('atl', []) - angular.mock.module('atl') -}) - -test('`fireEvent` triggers a digest', () => { - angular.module('atl').component('atlDigest', { - template: ` - -
- Clicked! -
- `, - controller: class { - wasClicked = false - btn = null - $postLink() { - this.btn.on('click', this.handleClick) - } - - handleClick = () => { - this.wasClicked = true - } - }, - }) - - const {getByRole, queryByText} = render(``) - - const button = getByRole('button') - expect(queryByText('Clicked!')).toBeNull() - fireEvent.click(button) - expect(queryByText('Clicked!')).not.toBeNull() -}) diff --git a/src/__tests__/end-to-end.js b/src/__tests__/end-to-end.ts similarity index 83% rename from src/__tests__/end-to-end.js rename to src/__tests__/end-to-end.ts index 457f097..f577778 100644 --- a/src/__tests__/end-to-end.js +++ b/src/__tests__/end-to-end.ts @@ -1,17 +1,21 @@ -import angular from 'angular' +import * as angular from 'angular' import 'angular-mocks' import {render, wait} from '../' +type FakeResponse = { + returnedMessage: string +} + class controller { loading = true - data = null + data?: FakeResponse - constructor($q, $timeout) { - this.$q = $q - this.$timeout = $timeout - } + constructor( + private $q: angular.IQService, + private $timeout: angular.ITimeoutService, + ) {} - load() { + load(): angular.IPromise { return this.$q(resolve => { // we are using random timeout here to simulate a real-time example // of an async operation calling a callback at a non-deterministic time diff --git a/src/__tests__/events.js b/src/__tests__/events.ts similarity index 93% rename from src/__tests__/events.js rename to src/__tests__/events.ts index 808494d..b039ed9 100644 --- a/src/__tests__/events.js +++ b/src/__tests__/events.ts @@ -1,6 +1,13 @@ import {render, fireEvent} from '../' -const eventTypes = [ +type EventType = { + type: string + events: Array + elementType: string + init?: object +} + +const eventTypes: EventType[] = [ { type: 'Clipboard', events: ['copy', 'paste'], @@ -146,7 +153,7 @@ eventTypes.forEach(({type, events, elementType, init}) => { }, ) - fireEvent[eventName](container.firstChild, init) + fireEvent[eventName](container.firstElementChild as Element, init) expect(spy).toHaveBeenCalledTimes(1) }) }) @@ -174,7 +181,6 @@ test('calling `fireEvent` directly works too', () => { new Event('click', { bubbles: true, cancelable: true, - button: 0, }), ) expect(spy).toHaveBeenCalledTimes(1) diff --git a/src/__tests__/multi-base.js b/src/__tests__/multi-base.ts similarity index 86% rename from src/__tests__/multi-base.js rename to src/__tests__/multi-base.ts index 77b2372..f5702e5 100644 --- a/src/__tests__/multi-base.js +++ b/src/__tests__/multi-base.ts @@ -1,7 +1,8 @@ import {render} from '../' // these are created once per test suite and reused for each case -let treeA, treeB +let treeA: HTMLDivElement +let treeB: HTMLDivElement beforeAll(() => { treeA = document.createElement('div') treeB = document.createElement('div') @@ -10,8 +11,8 @@ beforeAll(() => { }) afterAll(() => { - treeA.parentNode.removeChild(treeA) - treeB.parentNode.removeChild(treeB) + (treeA.parentNode as Node).removeChild(treeA) + ;(treeB.parentNode as Node).removeChild(treeB) }) test('baseElement isolates trees from one another', () => { diff --git a/src/__tests__/render.js b/src/__tests__/render.ts similarity index 93% rename from src/__tests__/render.js rename to src/__tests__/render.ts index 4e1bc05..2964bb9 100644 --- a/src/__tests__/render.js +++ b/src/__tests__/render.ts @@ -1,4 +1,4 @@ -import angular from 'angular' +import * as angular from 'angular' import 'angular-mocks' import {render} from '../' @@ -9,7 +9,7 @@ beforeEach(() => { test('renders div into document', () => { const {container} = render(`
`) - expect(container.firstChild.id).toBe('child') + expect((container.firstElementChild as Element).id).toBe('child') }) test('returns baseElement which defaults to document.body', () => { diff --git a/src/__tests__/stopwatch.js b/src/__tests__/stopwatch.ts similarity index 86% rename from src/__tests__/stopwatch.js rename to src/__tests__/stopwatch.ts index 51771fc..f2e45fe 100644 --- a/src/__tests__/stopwatch.js +++ b/src/__tests__/stopwatch.ts @@ -1,23 +1,24 @@ -import angular from 'angular' +import * as angular from 'angular' import 'angular-mocks' import {render, fireEvent, wait} from '../' class StopWatch { + timer!: angular.IPromise lapse = 0 running = false - constructor($interval) { + constructor(private $interval: angular.IIntervalService) { this.$interval = $interval } handleRunClick = () => { if (this.running) { - clearInterval(this.timer) + this.$interval.cancel(this.timer) } else { const startTime = Date.now() - this.lapse this.timer = this.$interval(() => { this.lapse = Date.now() - startTime - }) + }, 0) } this.running = !this.running } @@ -70,5 +71,5 @@ test('unmounts a component', async () => { unmount() - expect($scope.$$destroyed).toBe(true) + expect(($scope as any).$$destroyed).toBe(true) }) diff --git a/src/index.js b/src/index.ts similarity index 90% rename from src/index.js rename to src/index.ts index 30bc039..91a09d2 100644 --- a/src/index.js +++ b/src/index.ts @@ -1,5 +1,7 @@ import {flush, cleanup} from './pure' +declare function afterEach(cb: () => void): void + // if we're running in a test runner that supports afterEach // then we'll automatically run cleanup afterEach test // this ensures that tests run in isolation from each other diff --git a/src/pure.js b/src/pure.ts similarity index 56% rename from src/pure.js rename to src/pure.ts index 88e0b3a..9509a5f 100644 --- a/src/pure.js +++ b/src/pure.ts @@ -1,25 +1,57 @@ -import angular from 'angular' +import * as angular from 'angular' +import { + ICompileService, + IScope, + IRootScopeService, + IIntervalService, + IFlushPendingTasksService, +} from 'angular' import 'angular-mocks' import { getQueriesForElement, prettyDOM, fireEvent as dtlFireEvent, wait as dtlWait, + queries as dtlQueries, + Queries, + BoundFunction, } from '@testing-library/dom' -const mountedContainers = new Set() -const mountedScopes = new Set() +const mountedContainers = new Set() +const mountedScopes = new Set() + +type RenderOptions = { + container?: HTMLElement + baseElement?: HTMLElement + queries?: Q + scope?: object + ignoreUnknownElements?: boolean +} + +type RenderResult = { + container: HTMLElement + baseElement: HTMLElement + debug: ( + baseElement?: + | HTMLElement + | DocumentFragment + | Array, + ) => void + unmount: () => void + asFragment: () => DocumentFragment + $scope: IScope +} & {[P in keyof Q]: BoundFunction} function render( - ui, + ui: string, { container, baseElement = container, queries, scope, - ignoreUnknownElements, - } = {}, -) { + ignoreUnknownElements = false, + }: RenderOptions = {}, +): RenderResult { if (!baseElement) { // default to document.body instead of documentElement to avoid output of potentially-large // head elements (such as JSS style blocks) in debug output @@ -34,8 +66,8 @@ function render( // they're passing us a custom container or not. mountedContainers.add(container) - const $rootScope = inject('$rootScope') - const $compile = inject('$compile') + const $rootScope = inject('$rootScope') + const $compile = inject('$compile') const $scope = $rootScope.$new() Object.assign($scope, scope) @@ -56,19 +88,18 @@ function render( debug: (el = baseElement) => Array.isArray(el) ? // eslint-disable-next-line no-console - el.forEach(e => console.log(prettyDOM(e))) + el.forEach(e => console.log(prettyDOM(e as HTMLElement))) : // eslint-disable-next-line no-console, - console.log(prettyDOM(el)), + console.log(prettyDOM(el as HTMLElement)), asFragment: () => { + const source = container as HTMLElement /* istanbul ignore if (jsdom limitation) */ if (typeof document.createRange === 'function') { - return document - .createRange() - .createContextualFragment(container.innerHTML) + return document.createRange().createContextualFragment(source.innerHTML) } const template = document.createElement('template') - template.innerHTML = container.innerHTML + template.innerHTML = source.innerHTML return template.content }, $scope, @@ -86,28 +117,28 @@ function cleanup() { // maybe one day we'll expose this (perhaps even as a utility returned by render). // but let's wait until someone asks for it. -function cleanupAtContainer(container) { +function cleanupAtContainer(container: HTMLElement) { if (container.parentNode === document.body) { document.body.removeChild(container) } mountedContainers.delete(container) } -function cleanupScope(scope) { +function cleanupScope(scope: IScope) { scope.$destroy() mountedScopes.delete(scope) } -function toCamel(s) { +function toCamel(s: string) { return s .toLowerCase() .replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) } -function assertNoUnknownElements(element) { +function assertNoUnknownElements(element: Element) { const {tagName} = element if (tagName.includes('-')) { - const $injector = inject('$injector') + const $injector = inject('$injector') const directiveName = `${toCamel(tagName)}Directive` if (!$injector.has(directiveName)) { throw Error( @@ -118,7 +149,7 @@ function assertNoUnknownElements(element) { Array.from(element.children).forEach(assertNoUnknownElements) } -function inject(name) { +function inject(name: string): T { let service angular.mock.inject([ name, @@ -126,39 +157,30 @@ function inject(name) { service = injected }, ]) - return service -} - -function fireEvent(...args) { - const $rootScope = inject('$rootScope') - const result = dtlFireEvent(...args) - $rootScope.$digest() - return result + return (service as unknown) as T } -Object.keys(dtlFireEvent).forEach(key => { - fireEvent[key] = (...args) => { - const $rootScope = inject('$rootScope') - const result = dtlFireEvent[key](...args) - $rootScope.$digest() - return result - } -}) - // AngularJS maps `mouseEnter` to `mouseOver` and `mouseLeave` to `mouseOut` -fireEvent.mouseEnter = fireEvent.mouseOver -fireEvent.mouseLeave = fireEvent.mouseOut +// Create a copy so we can alter it +const fireEvent = dtlFireEvent.bind(null) +Object.assign(fireEvent, dtlFireEvent) + +fireEvent.mouseEnter = dtlFireEvent.mouseOver +fireEvent.mouseLeave = dtlFireEvent.mouseOut function flush(millis = 50) { - const $browser = inject('$browser') - const $rootScope = inject('$rootScope') - const $interval = inject('$interval') + const $flushPendingTasks = inject( + '$flushPendingTasks', + ) + const $rootScope = inject('$rootScope') + const $interval = inject('$interval') $interval.flush(millis) - $browser.defer.flush(millis) + $flushPendingTasks(millis) $rootScope.$digest() } -function wait(callback, options = {}) { +type WaitOptions = Parameters[1] +function wait(callback?: () => void, options: WaitOptions = {}) { return dtlWait(() => { flush(options.interval) if (callback) { diff --git a/tests/setup-env.js b/tests/setup-env.js deleted file mode 100644 index 264828a..0000000 --- a/tests/setup-env.js +++ /dev/null @@ -1 +0,0 @@ -import '@testing-library/jest-dom/extend-expect' diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..4e9c95c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,78 @@ +{ + "compilerOptions": { + /* Basic Options */ + "incremental": true /* Enable incremental compilation */, + "target": + "es2019" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */, + "module": + "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */, + // "lib": [], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true /* Generates corresponding '.d.ts' file. */, + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./lib" /* Redirect output structure to the directory. */, + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + "noEmit": true /* Do not emit outputs. */, + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + "noUnusedLocals": true /* Report errors on unused locals. */, + "noUnusedParameters": true /* Report errors on unused parameters. */, + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": + "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */, + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": { + // "src/*": ["/dev/null"], // Enforce relative paths + + // }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + "types": [ + "node", + "jest", + "@testing-library/jest-dom/extend-expect" + ] /* Type declaration files to be included in compilation. */, + "allowSyntheticDefaultImports": true /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */, + // "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + }, + "include": ["src/**/*", "src/__tests__"], + "exclude": ["node_modules"] +}