From ff829dc89f9022e3c8b70cf4f8abb316024db468 Mon Sep 17 00:00:00 2001 From: Rayat Rahman Date: Fri, 6 Aug 2021 10:03:30 -0700 Subject: [PATCH 1/6] chore(types): Add @types for lz-string --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 78ddf6c9..be6cb65a 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ }, "devDependencies": { "@testing-library/jest-dom": "^5.11.6", + "@types/lz-string": "^1.3.34", "jest-in-case": "^1.0.2", "jest-serializer-ansi": "^1.0.3", "jest-watch-select-projects": "^2.0.0", From d34f235398090e9c72ef6616768fceb76ce0924a Mon Sep 17 00:00:00 2001 From: Rayat Rahman Date: Fri, 6 Aug 2021 11:10:31 -0700 Subject: [PATCH 2/6] chore(types): Typescript migrate src/screen.js -> src/screen.ts (#494) Also update test snapshots --- src/__tests__/get-user-code-frame.js | 28 ++++++++++++------------ src/{screen.js => screen.ts} | 32 ++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 23 deletions(-) rename src/{screen.js => screen.ts} (62%) diff --git a/src/__tests__/get-user-code-frame.js b/src/__tests__/get-user-code-frame.js index 8d2bd058..6befcc78 100644 --- a/src/__tests__/get-user-code-frame.js +++ b/src/__tests__/get-user-code-frame.js @@ -39,13 +39,13 @@ test('it returns only user code frame when code frames from node_modules are fir const userTrace = getUserCodeFrame(stack) expect(userTrace).toMatchInlineSnapshot(` - /sample-error/error-example.js:7:14 - 5 | document.createTextNode('Hello world') - 6 | ) - > 7 | screen.debug() - | ^ - - `) +"/sample-error/error-example.js:7:14 + 5 | document.createTextNode('Hello world') + 6 | ) +> 7 | screen.debug() + | ^ +" +`) }) test('it returns only user code frame when node code frames are present afterwards', () => { @@ -59,13 +59,13 @@ test('it returns only user code frame when node code frames are present afterwar const userTrace = getUserCodeFrame() expect(userTrace).toMatchInlineSnapshot(` - /sample-error/error-example.js:7:14 - 5 | document.createTextNode('Hello world') - 6 | ) - > 7 | screen.debug() - | ^ - - `) +"/sample-error/error-example.js:7:14 + 5 | document.createTextNode('Hello world') + 6 | ) +> 7 | screen.debug() + | ^ +" +`) }) test("it returns empty string if file from code frame can't be read", () => { diff --git a/src/screen.js b/src/screen.ts similarity index 62% rename from src/screen.js rename to src/screen.ts index 5cbdd2de..05a163a4 100644 --- a/src/screen.js +++ b/src/screen.ts @@ -1,33 +1,40 @@ import {compressToEncodedURIComponent} from 'lz-string' -import * as queries from './queries' +import type {OptionsReceived} from 'pretty-format' import {getQueriesForElement} from './get-queries-for-element' -import {logDOM} from './pretty-dom' import {getDocument} from './helpers' +import {logDOM} from './pretty-dom' +import * as queries from './queries' -function unindent(string) { +function unindent(string: string) { // remove white spaces first, to save a few bytes. // testing-playground will reformat on load any ways. return string.replace(/[ \t]*[\n][ \t]*/g, '\n') } -function encode(value) { +function encode(value: string) { return compressToEncodedURIComponent(unindent(value)) } -function getPlaygroundUrl(markup) { +function getPlaygroundUrl(markup: string) { return `https://testing-playground.com/#markup=${encode(markup)}` } -const debug = (element, maxLength, options) => +const debug = ( + element: (Element | HTMLDocument)[], + maxLength?: number, + options?: OptionsReceived, +) => Array.isArray(element) ? element.forEach(el => logDOM(el, maxLength, options)) : logDOM(element, maxLength, options) const logTestingPlaygroundURL = (element = getDocument().body) => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!element || !('innerHTML' in element)) { console.log(`The element you're providing isn't a valid DOM element.`) return } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (!element.innerHTML) { console.log(`The provided element doesn't have any children.`) return @@ -37,11 +44,14 @@ const logTestingPlaygroundURL = (element = getDocument().body) => { ) } -const initialValue = {debug, logTestingPlaygroundURL} +const initialValue: { + [key in keyof typeof queries | 'debug' | 'logTestingPlaygroundURL']?: Function +} = {debug, logTestingPlaygroundURL} + export const screen = - typeof document !== 'undefined' && document.body + typeof document !== 'undefined' && document.body // eslint-disable-line @typescript-eslint/no-unnecessary-condition ? getQueriesForElement(document.body, queries, initialValue) - : Object.keys(queries).reduce((helpers, key) => { + : typedKeysOf(queries).reduce((helpers, key) => { helpers[key] = () => { throw new TypeError( 'For queries bound to document.body a global document has to be available... Learn more: https://testing-library.com/s/screen-global-error', @@ -49,3 +59,7 @@ export const screen = } return helpers }, initialValue) + +function typedKeysOf(o: O) { + return Object.keys(o) as Array +} From 8e9614bb3d6ba82fc47ef7d0ea15619c067cebb0 Mon Sep 17 00:00:00 2001 From: Rayat Rahman Date: Thu, 12 Aug 2021 17:45:27 -0400 Subject: [PATCH 3/6] chore(types): Simply types in src/screen.ts --- src/screen.ts | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/screen.ts b/src/screen.ts index 05a163a4..7500edd1 100644 --- a/src/screen.ts +++ b/src/screen.ts @@ -44,22 +44,16 @@ const logTestingPlaygroundURL = (element = getDocument().body) => { ) } -const initialValue: { - [key in keyof typeof queries | 'debug' | 'logTestingPlaygroundURL']?: Function -} = {debug, logTestingPlaygroundURL} +const initialValue = {debug, logTestingPlaygroundURL} export const screen = typeof document !== 'undefined' && document.body // eslint-disable-line @typescript-eslint/no-unnecessary-condition ? getQueriesForElement(document.body, queries, initialValue) - : typedKeysOf(queries).reduce((helpers, key) => { - helpers[key] = () => { + : Object.keys(queries).reduce((helpers, key) => { + helpers[key as keyof typeof initialValue] = () => { throw new TypeError( 'For queries bound to document.body a global document has to be available... Learn more: https://testing-library.com/s/screen-global-error', ) } return helpers }, initialValue) - -function typedKeysOf(o: O) { - return Object.keys(o) as Array -} From f8a12210b58958e618e2134c5ed7c9c84cf44e16 Mon Sep 17 00:00:00 2001 From: Rayat Rahman Date: Mon, 16 Aug 2021 15:21:17 -0700 Subject: [PATCH 4/6] chore(types): Add comment for type assertion --- src/screen.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/screen.ts b/src/screen.ts index 7500edd1..f3c4d8c0 100644 --- a/src/screen.ts +++ b/src/screen.ts @@ -50,6 +50,9 @@ export const screen = typeof document !== 'undefined' && document.body // eslint-disable-line @typescript-eslint/no-unnecessary-condition ? getQueriesForElement(document.body, queries, initialValue) : Object.keys(queries).reduce((helpers, key) => { + // `key` is for all intents and purposes the type of keyof `helpers`, which itself is the type of `initialValue` plus incoming properties from `queries` + // if `Object.keys(something)` returned Array this explicit type assertion would not be necessary + // see https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript helpers[key as keyof typeof initialValue] = () => { throw new TypeError( 'For queries bound to document.body a global document has to be available... Learn more: https://testing-library.com/s/screen-global-error', From 99952dd6da58be441b046cf8ea137f8d2f24f51f Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 25 Aug 2021 10:39:05 +0200 Subject: [PATCH 5/6] Revert snapshot changes --- src/__tests__/get-user-code-frame.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/__tests__/get-user-code-frame.js b/src/__tests__/get-user-code-frame.js index 6befcc78..8d2bd058 100644 --- a/src/__tests__/get-user-code-frame.js +++ b/src/__tests__/get-user-code-frame.js @@ -39,13 +39,13 @@ test('it returns only user code frame when code frames from node_modules are fir const userTrace = getUserCodeFrame(stack) expect(userTrace).toMatchInlineSnapshot(` -"/sample-error/error-example.js:7:14 - 5 | document.createTextNode('Hello world') - 6 | ) -> 7 | screen.debug() - | ^ -" -`) + /sample-error/error-example.js:7:14 + 5 | document.createTextNode('Hello world') + 6 | ) + > 7 | screen.debug() + | ^ + + `) }) test('it returns only user code frame when node code frames are present afterwards', () => { @@ -59,13 +59,13 @@ test('it returns only user code frame when node code frames are present afterwar const userTrace = getUserCodeFrame() expect(userTrace).toMatchInlineSnapshot(` -"/sample-error/error-example.js:7:14 - 5 | document.createTextNode('Hello world') - 6 | ) -> 7 | screen.debug() - | ^ -" -`) + /sample-error/error-example.js:7:14 + 5 | document.createTextNode('Hello world') + 6 | ) + > 7 | screen.debug() + | ^ + + `) }) test("it returns empty string if file from code frame can't be read", () => { From 9dcdf7f73c132062735ade231c6685c9a1da49ae Mon Sep 17 00:00:00 2001 From: eps1lon Date: Wed, 25 Aug 2021 10:40:26 +0200 Subject: [PATCH 6/6] Match type of published declarations --- src/screen.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.ts b/src/screen.ts index f3c4d8c0..caae921d 100644 --- a/src/screen.ts +++ b/src/screen.ts @@ -20,10 +20,10 @@ function getPlaygroundUrl(markup: string) { } const debug = ( - element: (Element | HTMLDocument)[], + element?: Array | Element | HTMLDocument, maxLength?: number, options?: OptionsReceived, -) => +): void => Array.isArray(element) ? element.forEach(el => logDOM(el, maxLength, options)) : logDOM(element, maxLength, options)