Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
"@vitest/coverage-v8": "4.0.18",
"@vue/test-utils": "2.4.6",
"axe-core": "4.11.1",
"fast-check": "4.5.3",
"fast-npm-meta": "1.0.0",
"knip": "5.83.0",
"lint-staged": "16.2.7",
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 69 additions & 0 deletions test/unit/server/utils/docs/text.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { describe, expect, it } from 'vitest'
import * as fc from 'fast-check'
import {
escapeHtml,
parseJsDocLinks,
Expand Down Expand Up @@ -40,6 +41,15 @@ describe('stripAnsi', () => {
const input = `object is ReactElement${ESC}[0m${ESC}[38;5;12m<${ESC}[0mP${ESC}[38;5;12m>${ESC}[0m`
expect(stripAnsi(input)).toBe('object is ReactElement<P>')
})

it('should strip everything in one pass', () => {
fc.assert(
fc.property(fc.string(), input => {
const stripped = stripAnsi(input)
expect(stripAnsi(stripped)).toBe(stripped)
}),
)
})
})

describe('escapeHtml', () => {
Expand Down Expand Up @@ -124,6 +134,65 @@ describe('parseJsDocLinks', () => {
const result = parseJsDocLinks('{@link http://example.com}', emptyLookup)
expect(result).toContain('href="http://example.com"')
})

it('should convert external URLs using {@link url} to links', () => {
fc.assert(
fc.property(fc.webUrl(), url => {
const result = parseJsDocLinks(`{@link ${url}}`, emptyLookup)
expect(result).toContain(`href="${escapeHtml(url)}"`)
expect(result).toContain('target="_blank"')
expect(result).toContain('rel="noreferrer"')
expect(result).toContain(escapeHtml(url))
}),
)
})

it('should convert external URLs using {@link url text} to links', () => {
fc.assert(
fc.property(fc.webUrl(), fc.stringMatching(/^[^}\s][^}]+[^}\s]$/), (url, text) => {
const result = parseJsDocLinks(`{@link ${url} ${text}}`, emptyLookup)
expect(result).toContain(`href="${escapeHtml(url)}"`)
expect(result).toContain('target="_blank"')
expect(result).toContain('rel="noreferrer"')
expect(result).toContain(escapeHtml(text))
}),
)
})

it('should be able to treat correctly several external URLs at the middle of a text', () => {
const surrounding = fc.stringMatching(/^[^{]*$/)
const link = fc.record({
url: fc.webUrl(),
label: fc.option(fc.stringMatching(/^[^}\s][^}]+[^}\s]$/)),
before: surrounding,
after: surrounding,
})
fc.assert(
fc.property(fc.array(link, { minLength: 1 }), content => {
let docString = ''
const expectedUrls = []
for (const chunk of content) {
if (chunk.before.length !== 0 || docString.length !== 0) {
docString += `${chunk.before} `
}
if (chunk.label === null) {
docString += `{@link ${chunk.url}}`
expectedUrls.push(chunk.url)
} else {
docString += `{@link ${chunk.url} ${chunk.label}}`
expectedUrls.push(chunk.url)
}
if (chunk.after.length !== 0) {
docString += ` ${chunk.after}`
}
}
const result = parseJsDocLinks(docString, emptyLookup)
for (const url of expectedUrls) {
expect(result).toContain(`href="${escapeHtml(url)}"`)
}
}),
)
})
})

describe('renderMarkdown', () => {
Expand Down
41 changes: 41 additions & 0 deletions test/unit/shared/utils/async.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { describe, expect, it, vi } from 'vitest'
import * as fc from 'fast-check'
import { mapWithConcurrency } from '../../../../shared/utils/async'

describe('mapWithConcurrency', () => {
Expand Down Expand Up @@ -92,4 +93,44 @@ describe('mapWithConcurrency', () => {
// Should only have 3 concurrent since we only have 3 items
expect(maxConcurrent).toBe(3)
})

it('waits for all tasks to succeed and return them in order whatever their count and the concurrency', async () => {
await fc.assert(
fc.asyncProperty(
fc.array(fc.anything()),
fc.integer({ min: 1 }),
fc.scheduler(),
async (items, concurrency, s) => {
const fn = s.scheduleFunction(async item => item)
const results = await s.waitFor(mapWithConcurrency(items, fn, concurrency))
expect(results).toEqual(items)
},
),
)
})

it('not run more than concurrency tasks in parallel', async () => {
await fc.assert(
fc.asyncProperty(
fc.array(fc.anything()),
fc.integer({ min: 1 }),
fc.scheduler(),
async (items, concurrency, s) => {
let tooManyRunningTasksEncountered = false
let currentlyRunning = 0
const fn = async (item: (typeof items)[number]) => {
currentlyRunning++
if (currentlyRunning > concurrency) {
tooManyRunningTasksEncountered = true
}
const task = s.schedule(Promise.resolve(item))
task.then(() => currentlyRunning--) // this task always succeeds by construct
return task
}
await s.waitFor(mapWithConcurrency(items, fn, concurrency))
expect(tooManyRunningTasksEncountered).toBe(false)
},
),
)
})
})
Loading