Skip to content

Commit

Permalink
add kcd-scripts, adjust for lint rules
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Oct 10, 2024
1 parent 325d59e commit b8d122c
Show file tree
Hide file tree
Showing 14 changed files with 8,418 additions and 1,603 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tsup.config.ts
dist/
18 changes: 18 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
extends: 'kentcdodds',
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-interface': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/unified-signatures': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
args: 'after-used',
argsIgnorePattern: '^_',
ignoreRestSiblings: true,
varsIgnorePattern: '^_',
},
],
},
}
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# format with kcd-scripts
325d59e3cd0bf4c7ab738381e1bb49aef3bc7363
1 change: 1 addition & 0 deletions .prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("kcd-scripts/prettier.js");
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
"@types/react": "^18",
"@types/react-dom": "^18",
"expect": "^29.7.0",
"kcd-scripts": "^16.0.0",
"pkg-pr-new": "^0.0.29",
"prettier": "^3.3.3",
"publint": "^0.2.11",
Expand All @@ -79,7 +80,12 @@
"build": "tsup",
"pkg-pr-new-publish": "yarn build && pkg-pr-new publish --no-template",
"prepack": "yarn build",
"format": "kcd-scripts format",
"lint": "kcd-scripts lint --config .eslintrc.cjs",
"verify": "attw --pack . && publint"
},
"packageManager": "[email protected]"
"packageManager": "[email protected]",
"resolutions": {
"eslint-config-kentcdodds": "^21.0.0"
}
}
2 changes: 1 addition & 1 deletion src/assertable.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {RenderStream} from './renderStream/createRenderStream.js'
import {type RenderStream} from './renderStream/createRenderStream.js'

export const assertableSymbol = Symbol.for(
'@testing-library/react-render-stream:assertable',
Expand Down
9 changes: 7 additions & 2 deletions src/jest/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import {expect} from '@jest/globals'
import {toRerender, toRenderExactlyTimes} from './renderStreamMatchers.js'
import type {RenderStreamMatchers} from './renderStreamMatchers.js'
import {
toRerender,
toRenderExactlyTimes,
type RenderStreamMatchers,
} from './renderStreamMatchers.js'

expect.extend({
toRerender,
toRenderExactlyTimes,
})

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface Matchers<R = void, T = {}> extends RenderStreamMatchers<R, T> {}
}
}
32 changes: 19 additions & 13 deletions src/jest/renderStreamMatchers.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {MatcherFunction} from 'expect'
import {WaitForRenderTimeoutError} from '@testing-library/react-render-stream'
import type {
Assertable,
NextRenderOptions,
RenderStream,
import {MatcherContext, type MatcherFunction} from 'expect'
import {
WaitForRenderTimeoutError,
type Assertable,
type NextRenderOptions,
type RenderStream,
} from '@testing-library/react-render-stream'
// explicitly imported the symbol from the internal file
// this will bundle the `Symbol.for` call twice, but we keep it private
Expand All @@ -24,7 +24,7 @@ export interface RenderStreamMatchers<R = void, T = {}> {
}

export const toRerender: MatcherFunction<[options?: NextRenderOptions]> =
async function (actual, options) {
async function toRerender(this: MatcherContext, actual, options) {
const _stream = actual as RenderStream<any> | Assertable
const stream =
assertableSymbol in _stream ? _stream[assertableSymbol] : _stream
Expand All @@ -44,20 +44,24 @@ export const toRerender: MatcherFunction<[options?: NextRenderOptions]> =
pass,
message() {
return (
hint +
`\n\nExpected component to${pass ? ' not' : ''} rerender, ` +
`${hint}\n\nExpected component to${pass ? ' not' : ''} rerender, ` +
`but it did${pass ? '' : ' not'}.`
)
},
}
}

/** to be thrown to "break" test execution and fail it */
const failed = {}
const failed = new Error()

export const toRenderExactlyTimes: MatcherFunction<
[times: number, options?: NextRenderOptions]
> = async function (actual, times, optionsPerRender) {
> = async function toRenderExactlyTimes(
this: MatcherContext,
actual,
times,
optionsPerRender,
) {
const _stream = actual as RenderStream<any> | Assertable
const stream =
assertableSymbol in _stream ? _stream[assertableSymbol] : _stream
Expand All @@ -70,6 +74,7 @@ export const toRenderExactlyTimes: MatcherFunction<
}
try {
while (stream.totalRenderCount() < times) {
// eslint-disable-next-line no-await-in-loop
await stream.waitForNextRender(options)
}
} catch (e) {
Expand All @@ -95,8 +100,9 @@ export const toRenderExactlyTimes: MatcherFunction<
pass,
message() {
return (
hint +
` Expected component to${pass ? ' not' : ''} render exactly ${times}.` +
`${
hint
} Expected component to${pass ? ' not' : ''} render exactly ${times}.` +
` It rendered ${stream.totalRenderCount()} times.`
)
},
Expand Down
8 changes: 4 additions & 4 deletions src/renderHookToSnapshotStream.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {RenderHookOptions} from '@testing-library/react'
import {createElement} from 'rehackt'
import {createRenderStream} from './renderStream/createRenderStream.js'
import type {NextRenderOptions} from './renderStream/createRenderStream.js'
import {type NextRenderOptions} from './renderStream/createRenderStream.js'

import {Render} from './renderStream/Render.js'
import {createElement} from 'rehackt'
import {Assertable, assertableSymbol, markAssertable} from './assertable.js'

export interface SnapshotStream<Snapshot, Props> extends Assertable {
Expand Down Expand Up @@ -48,7 +48,7 @@ export interface SnapshotStream<Snapshot, Props> extends Assertable {

export function renderHookToSnapshotStream<ReturnValue, Props extends {}>(
renderCallback: (props: Props) => ReturnValue,
{initialProps, ...options}: RenderHookOptions<Props> = {},
{initialProps, ...renderOptions}: RenderHookOptions<Props> = {},
): SnapshotStream<ReturnValue, Props> {
const {render, ...stream} = createRenderStream<{value: ReturnValue}>()

Expand All @@ -59,7 +59,7 @@ export function renderHookToSnapshotStream<ReturnValue, Props extends {}>(

const {rerender: baseRerender, unmount} = render(
createElement(HookComponent, initialProps),
options,
renderOptions,
)

function rerender(rerenderCallbackProps: Props) {
Expand Down
14 changes: 10 additions & 4 deletions src/renderStream/Render.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,19 @@ export class RenderInstance<Snapshot> implements Render<Snapshot> {
startTime: number
commitTime: number
count: number
public snapshot: Snapshot
private stringifiedDOM: string | undefined
public renderedComponents: Array<string | React.ComponentType>

constructor(
baseRender: BaseRender,
public snapshot: Snapshot,
private stringifiedDOM: string | undefined,
public renderedComponents: Array<string | React.ComponentType>,
snapshot: Snapshot,
stringifiedDOM: string | undefined,
renderedComponents: Array<string | React.ComponentType>,
) {
this.snapshot = snapshot
this.stringifiedDOM = stringifiedDOM
this.renderedComponents = renderedComponents
this.id = baseRender.id
this.phase = baseRender.phase
this.actualDuration = baseRender.actualDuration
Expand Down Expand Up @@ -188,7 +194,7 @@ export function errorOnDomInteraction() {
throw new Error(`
DOM interaction with a snapshot detected in test.
Please don't interact with the DOM you get from \`withinDOM\`,
but still use \`screen\' to get elements for simulating user interaction.
but still use \`screen\` to get elements for simulating user interaction.
`)
}
events.forEach(event => {
Expand Down
Loading

0 comments on commit b8d122c

Please sign in to comment.