Skip to content

Commit 8395e5f

Browse files
cmdcolinclaude
andcommitted
fix lint: resolve all eslint errors in browser test
- allow numbers in restrict-template-expressions - fix non-null assertions, unnecessary optional chain, unused params - use proper types for puppeteer handlers (Error, ConsoleMessage) - replace null with undefined, use unknown instead of any in catch - add await in evaluate callbacks, extract appHandler to module scope - use default import for node:path per unicorn/import-style - add eslint-disable block for inherently untyped puppeteer evaluate calls Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 0d35096 commit 8395e5f

File tree

3 files changed

+95
-58
lines changed

3 files changed

+95
-58
lines changed

eslint.config.mjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export default defineConfig(
3333
rules: {
3434
'no-underscore-dangle': 'off',
3535
curly: 'error',
36+
eqeqeq: 'error',
3637
'@typescript-eslint/consistent-type-imports': 'error',
3738
semi: ['error', 'never'],
3839
'no-plusplus': 'off',
@@ -45,13 +46,18 @@ export default defineConfig(
4546
'unicorn/prefer-spread': 'off',
4647
'unicorn/expiring-todo-comments': 'off',
4748

49+
'@typescript-eslint/restrict-template-expressions': [
50+
'error',
51+
{ allowNumber: true },
52+
],
4853
'@typescript-eslint/no-explicit-any': 'warn',
4954
'@typescript-eslint/ban-ts-comment': [
5055
'error',
5156
{ 'ts-expect-error': 'allow-with-description', 'ts-ignore': true },
5257
],
5358

5459
'import/no-unresolved': 'off',
60+
'import/no-named-as-default-member': 'off',
5561
'import/extensions': ['error', 'ignorePackages'],
5662
'import/order': [
5763
'error',

src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@ export default class Trix {
6464
done = true
6565
}
6666
} else {
67-
const lines = str
68-
.slice(0, lastNewline)
69-
.split('\n')
70-
.filter(Boolean)
67+
const lines = str.slice(0, lastNewline).split('\n').filter(Boolean)
7168

7269
for (const line of lines) {
7370
const word = line.split(' ')[0]
@@ -178,7 +175,10 @@ export default class Trix {
178175
// or to ensure we have enough data to start with.
179176
if (end - start < CHUNK_SIZE) {
180177
const fileSize = await this.getIxFileSize(opts)
181-
end = fileSize === undefined ? start + CHUNK_SIZE : Math.min(start + CHUNK_SIZE, fileSize)
178+
end =
179+
fileSize === undefined
180+
? start + CHUNK_SIZE
181+
: Math.min(start + CHUNK_SIZE, fileSize)
182182
}
183183

184184
const buffer = await this.ixFile.read(end - start, start, opts)

test/browser.test.ts

Lines changed: 84 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { readFileSync, statSync } from 'node:fs'
22
import { createServer } from 'node:http'
3-
import { join } from 'node:path'
3+
import path from 'node:path'
44

55
import puppeteer from 'puppeteer'
66
import { afterAll, beforeAll, describe, expect, it } from 'vitest'
77

88
import type { IncomingMessage, ServerResponse } from 'node:http'
9-
import type { Browser, Page } from 'puppeteer'
9+
import type { Browser, ConsoleMessage, Page } from 'puppeteer'
1010

1111
function createStaticServer(
1212
port: number,
@@ -32,10 +32,10 @@ function createStaticServer(
3232
return
3333
}
3434

35-
const filePath = join(
35+
const filePath = path.join(
3636
process.cwd(),
3737
'test/testData/test1',
38-
req.url === '/' ? 'myTrix.ix' : req.url!,
38+
req.url === '/' ? 'myTrix.ix' : (req.url ?? '/'),
3939
)
4040

4141
try {
@@ -78,13 +78,12 @@ function createStaticServer(
7878
return createServer(handler)
7979
}
8080

81-
function createAppServer(port: number): ReturnType<typeof createServer> {
82-
const handler = (req: IncomingMessage, res: ServerResponse) => {
83-
res.setHeader('Access-Control-Allow-Origin', '*')
81+
function appHandler(req: IncomingMessage, res: ServerResponse) {
82+
res.setHeader('Access-Control-Allow-Origin', '*')
8483

85-
if (req.url === '/') {
86-
res.writeHead(200, { 'Content-Type': 'text/html' })
87-
res.end(`<!DOCTYPE html>
84+
if (req.url === '/') {
85+
res.writeHead(200, { 'Content-Type': 'text/html' })
86+
res.end(`<!DOCTYPE html>
8887
<html>
8988
<head>
9089
<script type="importmap">
@@ -105,32 +104,33 @@ function createAppServer(port: number): ReturnType<typeof createServer> {
105104
</script>
106105
</body>
107106
</html>`)
108-
return
109-
}
107+
return
108+
}
110109

111-
const filePath = join(process.cwd(), req.url!)
112-
try {
113-
const stat = statSync(filePath)
114-
if (stat.isFile()) {
115-
const content = readFileSync(filePath)
116-
const ext = filePath.split('.').pop()
117-
const contentType =
118-
ext === 'js' ? 'application/javascript' : 'application/octet-stream'
119-
res.writeHead(200, {
120-
'Content-Type': contentType,
121-
'Content-Length': content.length,
122-
})
123-
res.end(content)
124-
return
125-
}
126-
} catch {
127-
// fall through to 404
110+
const filePath = path.join(process.cwd(), req.url ?? '/')
111+
try {
112+
const stat = statSync(filePath)
113+
if (stat.isFile()) {
114+
const content = readFileSync(filePath)
115+
const ext = filePath.split('.').pop()
116+
const contentType =
117+
ext === 'js' ? 'application/javascript' : 'application/octet-stream'
118+
res.writeHead(200, {
119+
'Content-Type': contentType,
120+
'Content-Length': content.length,
121+
})
122+
res.end(content)
123+
return
128124
}
129-
res.writeHead(404)
130-
res.end('Not found')
125+
} catch {
126+
// fall through to 404
131127
}
128+
res.writeHead(404)
129+
res.end('Not found')
130+
}
132131

133-
return createServer(handler)
132+
function createAppServer() {
133+
return createServer(appHandler)
134134
}
135135

136136
describe('Browser tests with Puppeteer', () => {
@@ -146,7 +146,7 @@ describe('Browser tests with Puppeteer', () => {
146146
beforeAll(async () => {
147147
corsServer = createStaticServer(corsPort, true)
148148
noCorsServer = createStaticServer(noCorsPort, false)
149-
appServer = createAppServer(appPort)
149+
appServer = createAppServer()
150150

151151
await Promise.all([
152152
new Promise<void>(resolve => corsServer.listen(corsPort, resolve)),
@@ -161,7 +161,7 @@ describe('Browser tests with Puppeteer', () => {
161161
page = await browser.newPage()
162162

163163
const errors: string[] = []
164-
page.on('pageerror', (err: any) => errors.push(err.message))
164+
page.on('pageerror', (err: Error) => errors.push(err.message))
165165
page.on('console', msg => {
166166
if (msg.type() === 'error') {
167167
errors.push(msg.text())
@@ -181,21 +181,38 @@ describe('Browser tests with Puppeteer', () => {
181181
}, 30000)
182182

183183
afterAll(async () => {
184-
await browser?.close()
184+
await browser.close()
185185
await Promise.all([
186-
new Promise<void>(resolve => corsServer.close(() => { resolve() })),
187-
new Promise<void>(resolve => noCorsServer.close(() => { resolve() })),
188-
new Promise<void>(resolve => appServer.close(() => { resolve() })),
186+
new Promise<void>(resolve =>
187+
corsServer.close(() => {
188+
resolve()
189+
}),
190+
),
191+
new Promise<void>(resolve =>
192+
noCorsServer.close(() => {
193+
resolve()
194+
}),
195+
),
196+
new Promise<void>(resolve =>
197+
appServer.close(() => {
198+
resolve()
199+
}),
200+
),
189201
])
190202
})
191203

204+
/* eslint-disable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
192205
it('searches via HTTP with CORS enabled server', async () => {
193206
const results = await page.evaluate(async (port: number) => {
194207
const trix = new (globalThis as any).Trix(
195-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ixx`),
196-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ix`),
208+
new (globalThis as any).RemoteFile(
209+
`http://localhost:${port}/myTrix.ixx`,
210+
),
211+
new (globalThis as any).RemoteFile(
212+
`http://localhost:${port}/myTrix.ix`,
213+
),
197214
)
198-
return trix.search('for')
215+
return await trix.search('for')
199216
}, corsPort)
200217

201218
expect(results.length).toBeGreaterThan(0)
@@ -204,24 +221,29 @@ describe('Browser tests with Puppeteer', () => {
204221

205222
it('fails to search via HTTP without CORS (browser enforces CORS)', async () => {
206223
const consoleMessages: string[] = []
207-
const consoleHandler = (msg: any) => {
224+
const consoleHandler = (msg: ConsoleMessage) => {
208225
consoleMessages.push(msg.text())
209226
}
210227
page.on('console', consoleHandler)
211228

212229
const result = await page.evaluate(async (port: number) => {
213230
const trix = new (globalThis as any).Trix(
214-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ixx`),
215-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ix`),
231+
new (globalThis as any).RemoteFile(
232+
`http://localhost:${port}/myTrix.ixx`,
233+
),
234+
new (globalThis as any).RemoteFile(
235+
`http://localhost:${port}/myTrix.ix`,
236+
),
216237
)
217238
try {
218239
await trix.search('for')
219-
return { success: true, error: null, errorName: null }
220-
} catch (error: any) {
240+
return { success: true, error: undefined, errorName: undefined }
241+
} catch (error: unknown) {
242+
const name = error instanceof Error ? error.name : undefined
221243
return {
222244
success: false,
223245
error: String(error),
224-
errorName: error?.name || null,
246+
errorName: name,
225247
}
226248
}
227249
}, noCorsPort)
@@ -243,10 +265,14 @@ describe('Browser tests with Puppeteer', () => {
243265
it('handles EOF correctly with CORS enabled server', async () => {
244266
const results = await page.evaluate(async (port: number) => {
245267
const trix = new (globalThis as any).Trix(
246-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ixx`),
247-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ix`),
268+
new (globalThis as any).RemoteFile(
269+
`http://localhost:${port}/myTrix.ixx`,
270+
),
271+
new (globalThis as any).RemoteFile(
272+
`http://localhost:${port}/myTrix.ix`,
273+
),
248274
)
249-
return trix.search('this')
275+
return await trix.search('this')
250276
}, corsPort)
251277

252278
expect(results).toMatchSnapshot()
@@ -255,12 +281,17 @@ describe('Browser tests with Puppeteer', () => {
255281
it('returns empty for non-existent search term', async () => {
256282
const results = await page.evaluate(async (port: number) => {
257283
const trix = new (globalThis as any).Trix(
258-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ixx`),
259-
new (globalThis as any).RemoteFile(`http://localhost:${port}/myTrix.ix`),
284+
new (globalThis as any).RemoteFile(
285+
`http://localhost:${port}/myTrix.ixx`,
286+
),
287+
new (globalThis as any).RemoteFile(
288+
`http://localhost:${port}/myTrix.ix`,
289+
),
260290
)
261-
return trix.search('zzz')
291+
return await trix.search('zzz')
262292
}, corsPort)
263293

264294
expect(results).toEqual([])
265295
})
296+
/* eslint-enable @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any */
266297
})

0 commit comments

Comments
 (0)