mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 10:56:15 -08:00
feat: add build:test script and improve documentation code blocks
- Added a new script `build:test` to generate test cases from documentation code examples. - Enhanced documentation files by ensuring proper code block formatting and adding missing closing backticks. - Updated various markdown files to include new code blocks and fixed formatting issues.
This commit is contained in:
1 parent
5cc8d14454
commit
7bfee6c6dc
17 files changed
+4857
-19
No files matched your search
@@ -35,12 +35,12 @@
|
|||||||
</script>
|
</script>
|
||||||
<script src="../compiled/artplayer.js"></script>
|
<script src="../compiled/artplayer.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-ads.js"></script>
|
<script src="../compiled/artplayer-plugin-ads.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-control.js"></script>
|
|
||||||
<script src="../compiled/artplayer-plugin-danmuku.js"></script>
|
<script src="../compiled/artplayer-plugin-danmuku.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-dash-quality.js"></script>
|
<script src="../compiled/artplayer-plugin-dash-control.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-hls-quality.js"></script>
|
<script src="../compiled/artplayer-plugin-hls-control.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-iframe.js"></script>
|
<script src="../compiled/artplayer-plugin-iframe.js"></script>
|
||||||
<script src="../compiled/artplayer-plugin-vtt-thumbnail.js"></script>
|
<script src="../compiled/artplayer-plugin-vtt-thumbnail.js"></script>
|
||||||
|
<script src="../compiled/artplayer-plugin-chapter.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.17/hls.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/hls.js/1.5.17/hls.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.5.2/dash.all.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/dashjs/4.5.2/dash.all.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/flv.js/1.6.2/flv.min.js"></script>
|
||||||
|
|||||||
+4602
-5
File diff suppressed because it is too large.
Load diff
@@ -31,6 +31,7 @@
|
|||||||
"build:llm": "node ./scripts/build-llm.js",
|
"build:llm": "node ./scripts/build-llm.js",
|
||||||
"build:docs": "node ./scripts/build-docs.js",
|
"build:docs": "node ./scripts/build-docs.js",
|
||||||
"build:i18n": "node ./scripts/build-i18n.js",
|
"build:i18n": "node ./scripts/build-i18n.js",
|
||||||
|
"build:test": "node ./scripts/build-test.js",
|
||||||
"trans:docs": "node ./scripts/trans-docs.js",
|
"trans:docs": "node ./scripts/trans-docs.js",
|
||||||
"create:plugin": "node ./scripts/plugin/create.js",
|
"create:plugin": "node ./scripts/plugin/create.js",
|
||||||
"dev": "npx cross-env NODE_ENV=development node ./scripts/dev.js",
|
"dev": "npx cross-env NODE_ENV=development node ./scripts/dev.js",
|
||||||
|
|||||||
@@ -500,4 +500,5 @@ function myPlugin(art) {
|
|||||||
|
|
||||||
art.on('ready', () => {
|
art.on('ready', () => {
|
||||||
art.plugins.add(myPlugin);
|
art.plugins.add(myPlugin);
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -132,4 +132,5 @@ Returns the default options for the player.
|
|||||||
<div className="run-code">▶ Run Code</div>
|
<div className="run-code">▶ Run Code</div>
|
||||||
|
|
||||||
```js
|
```js
|
||||||
console.info(Artplayer.option);
|
console.info(Artplayer.option);
|
||||||
|
```
|
||||||
@@ -263,6 +263,8 @@ art.on('error', (error, reconnectTime) => {
|
|||||||
console.info(error, reconnectTime);
|
console.info(error, reconnectTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `hover`
|
## `hover`
|
||||||
|
|
||||||
Triggered when the mouse enters or leaves the player
|
Triggered when the mouse enters or leaves the player
|
||||||
@@ -521,6 +523,8 @@ art.on('pip', (state) => {
|
|||||||
console.info('pip', state);
|
console.info('pip', state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `screenshot`
|
## `screenshot`
|
||||||
|
|
||||||
Triggered when the player captures a screenshot
|
Triggered when the player captures a screenshot
|
||||||
@@ -774,6 +778,8 @@ art.on('setting', (state) => {
|
|||||||
console.log(state);
|
console.log(state);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `muted`
|
## `muted`
|
||||||
|
|
||||||
Triggered when the mute state changes
|
Triggered when the mute state changes
|
||||||
|
|||||||
@@ -251,6 +251,8 @@ var art = new Artplayer({
|
|||||||
url: '/assets/sample/404.mp4',
|
url: '/assets/sample/404.mp4',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## CONTROL_HIDE_TIME
|
## CONTROL_HIDE_TIME
|
||||||
|
|
||||||
The delay time in milliseconds for auto-hiding the bottom control bar. Default is `3000`.
|
The delay time in milliseconds for auto-hiding the bottom control bar. Default is `3000`.
|
||||||
@@ -499,6 +501,8 @@ var art = new Artplayer({
|
|||||||
art.contextmenu.show = true;
|
art.contextmenu.show = true;
|
||||||
art.setting.show = true;
|
art.setting.show = true;
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## FULLSCREEN_WEB_IN_BODY
|
## FULLSCREEN_WEB_IN_BODY
|
||||||
|
|
||||||
Determines whether to mount the player under the `body` element during web fullscreen mode. Defaults to `true`.
|
Determines whether to mount the player under the `body` element during web fullscreen mode. Defaults to `true`.
|
||||||
@@ -563,4 +567,5 @@ var art = new Artplayer({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Only destroys the UI, does not actively clear src
|
// Only destroys the UI, does not actively clear src
|
||||||
art.destroy();
|
art.destroy();
|
||||||
|
```
|
||||||
@@ -121,4 +121,5 @@ var art = new Artplayer({
|
|||||||
url: '/assets/sample/layer.png'
|
url: '/assets/sample/layer.png'
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -263,6 +263,8 @@ art.on('ready', () => {
|
|||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
:::warning Note
|
:::warning Note
|
||||||
|
|
||||||
`art.switch` and `art.switchUrl` have the same functionality, but the `art.switchUrl` method returns a `Promise`. It `resolve`s when the new URL is playable and `reject`s when the new URL fails to load.
|
`art.switch` and `art.switchUrl` have the same functionality, but the `art.switchUrl` method returns a `Promise`. It `resolve`s when the new URL is playable and `reject`s when the new URL fails to load.
|
||||||
@@ -1024,6 +1026,8 @@ art.on('ready', () => {
|
|||||||
}, 3000);
|
}, 3000);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `thumbnails`
|
## `thumbnails`
|
||||||
|
|
||||||
- Type: `Setter/Getter`
|
- Type: `Setter/Getter`
|
||||||
@@ -1068,4 +1072,5 @@ var art = new Artplayer({
|
|||||||
|
|
||||||
art.on('ready', () => {
|
art.on('ready', () => {
|
||||||
art.subtitleOffset = 1;
|
art.subtitleOffset = 1;
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -124,4 +124,5 @@ art.on('ready', () => {
|
|||||||
html: 'Your New Menu',
|
html: 'Your New Menu',
|
||||||
})
|
})
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -174,4 +174,5 @@ art.on('ready', () => {
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -143,4 +143,5 @@ art.on('ready', () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -168,6 +168,8 @@ var art = new Artplayer({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## Create - Toggle Button
|
## Create - Toggle Button
|
||||||
|
|
||||||
| Property | Type | Description |
|
| Property | Type | Description |
|
||||||
@@ -329,4 +331,5 @@ art.on('ready', () => {
|
|||||||
switch: false,
|
switch: false,
|
||||||
});
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -98,4 +98,5 @@ var art = new Artplayer({
|
|||||||
Play: 'Your Play'
|
Play: 'Your Play'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -268,6 +268,8 @@ var art = new Artplayer({
|
|||||||
autoSize: true,
|
autoSize: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `autoMini`
|
## `autoMini`
|
||||||
|
|
||||||
- Type: `Boolean`
|
- Type: `Boolean`
|
||||||
@@ -532,6 +534,8 @@ var art = new Artplayer({
|
|||||||
setting: true,
|
setting: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `miniProgressBar`
|
## `miniProgressBar`
|
||||||
|
|
||||||
- Type: `Boolean`
|
- Type: `Boolean`
|
||||||
@@ -742,6 +746,8 @@ var art = new Artplayer({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
:::warning For `Component Configuration`, please refer to:
|
:::warning For `Component Configuration`, please refer to:
|
||||||
|
|
||||||
[/component/controls.html](/component/controls.html)
|
[/component/controls.html](/component/controls.html)
|
||||||
@@ -943,6 +949,8 @@ var art = new Artplayer({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## `icons`
|
## `icons`
|
||||||
|
|
||||||
- Type: `Object`
|
- Type: `Object`
|
||||||
@@ -1243,4 +1251,5 @@ var art = new Artplayer({
|
|||||||
container: '.artplayer-app',
|
container: '.artplayer-app',
|
||||||
url: '/assets/sample/video.mp4',
|
url: '/assets/sample/video.mp4',
|
||||||
proxy: () => document.createElement('video')
|
proxy: () => document.createElement('video')
|
||||||
});
|
});
|
||||||
|
```
|
||||||
@@ -0,0 +1,132 @@
|
|||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
|
||||||
|
const docsDir = path.resolve('packages/artplayer-vitepress/docs/en')
|
||||||
|
const outputFile = path.resolve('docs/test/test.js')
|
||||||
|
|
||||||
|
// Regex to match code blocks after "Run Code" markers
|
||||||
|
// Match until we find a closing ``` that's on its own line
|
||||||
|
const runCodePattern = /<div className="run-code">.*?<\/div>\s*\n\s*```js[^\n]*\n([\s\S]*?)\n```(?=\s*\n|$)/g
|
||||||
|
|
||||||
|
function extractCodeBlocks(content, filePath) {
|
||||||
|
const blocks = []
|
||||||
|
let match
|
||||||
|
|
||||||
|
while ((match = runCodePattern.exec(content)) !== null) {
|
||||||
|
let code = match[1].trim()
|
||||||
|
|
||||||
|
// Skip if code contains markdown syntax (unclosed code block issue)
|
||||||
|
if (code.includes('\n## ') || code.includes('\n:::') || code.includes('<div className="run-code">')) {
|
||||||
|
console.warn(`⚠️ Skipping malformed code block in ${filePath}`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks.push({
|
||||||
|
code,
|
||||||
|
file: filePath,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return blocks
|
||||||
|
}
|
||||||
|
|
||||||
|
function processMarkdownFiles(dir, relativePath = '') {
|
||||||
|
const results = []
|
||||||
|
const items = fs.readdirSync(dir)
|
||||||
|
|
||||||
|
for (const item of items) {
|
||||||
|
const fullPath = path.join(dir, item)
|
||||||
|
const relPath = path.join(relativePath, item)
|
||||||
|
const stat = fs.statSync(fullPath)
|
||||||
|
|
||||||
|
if (stat.isDirectory()) {
|
||||||
|
results.push(...processMarkdownFiles(fullPath, relPath))
|
||||||
|
}
|
||||||
|
else if (item.endsWith('.md')) {
|
||||||
|
const content = fs.readFileSync(fullPath, 'utf-8')
|
||||||
|
const blocks = extractCodeBlocks(content, relPath)
|
||||||
|
if (blocks.length > 0) {
|
||||||
|
results.push({
|
||||||
|
file: relPath,
|
||||||
|
blocks,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateTestCode(fileResults) {
|
||||||
|
const lines = []
|
||||||
|
|
||||||
|
lines.push(`// Auto-generated smoke tests from documentation code blocks`)
|
||||||
|
lines.push(`// Generated at: ${new Date().toISOString()}`)
|
||||||
|
lines.push(`// Do not edit manually - run 'node scripts/build-test.js' to regenerate`)
|
||||||
|
lines.push(``)
|
||||||
|
lines.push(`describe('Documentation Code Examples', function () {`)
|
||||||
|
lines.push(` this.timeout(5000);`)
|
||||||
|
lines.push(``)
|
||||||
|
lines.push(` beforeEach(function () {`)
|
||||||
|
lines.push(` // Destroy any existing instances`)
|
||||||
|
lines.push(` [...Artplayer.instances].forEach((art) => art.destroy());`)
|
||||||
|
lines.push(` // Reset container`)
|
||||||
|
lines.push(` const container = document.querySelector('.artplayer-app');`)
|
||||||
|
lines.push(` if (container) {`)
|
||||||
|
lines.push(` container.innerHTML = '';`)
|
||||||
|
lines.push(` }`)
|
||||||
|
lines.push(` });`)
|
||||||
|
lines.push(``)
|
||||||
|
lines.push(` afterEach(function () {`)
|
||||||
|
lines.push(` [...Artplayer.instances].forEach((art) => art.destroy());`)
|
||||||
|
lines.push(` });`)
|
||||||
|
lines.push(``)
|
||||||
|
|
||||||
|
for (const { file, blocks } of fileResults) {
|
||||||
|
const suiteName = file.replace(/\.md$/, '').replace(/\//g, ' > ')
|
||||||
|
|
||||||
|
lines.push(` describe('${suiteName}', function () {`)
|
||||||
|
|
||||||
|
blocks.forEach((block, index) => {
|
||||||
|
const testName = `Example ${index + 1}`
|
||||||
|
// Escape the code for embedding in a string
|
||||||
|
const escapedCode = block.code
|
||||||
|
.replace(/\\/g, '\\\\')
|
||||||
|
.replace(/`/g, '\\`')
|
||||||
|
.replace(/\$/g, '\\$')
|
||||||
|
|
||||||
|
lines.push(` it('${testName}', function (done) {`)
|
||||||
|
lines.push(` try {`)
|
||||||
|
lines.push(` ${block.code.split('\n').join('\n ')}`)
|
||||||
|
lines.push(` // Wait a bit for async initialization`)
|
||||||
|
lines.push(` setTimeout(() => done(), 100);`)
|
||||||
|
lines.push(` } catch (err) {`)
|
||||||
|
lines.push(` done(err);`)
|
||||||
|
lines.push(` }`)
|
||||||
|
lines.push(` });`)
|
||||||
|
lines.push(``)
|
||||||
|
})
|
||||||
|
|
||||||
|
lines.push(` });`)
|
||||||
|
lines.push(``)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.push(`});`)
|
||||||
|
|
||||||
|
return lines.join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main execution
|
||||||
|
const fileResults = processMarkdownFiles(docsDir)
|
||||||
|
|
||||||
|
let totalBlocks = 0
|
||||||
|
for (const { file, blocks } of fileResults) {
|
||||||
|
console.log(`📄 ${file}: ${blocks.length} code blocks`)
|
||||||
|
totalBlocks += blocks.length
|
||||||
|
}
|
||||||
|
|
||||||
|
const testCode = generateTestCode(fileResults)
|
||||||
|
fs.writeFileSync(outputFile, testCode)
|
||||||
|
|
||||||
|
console.log(`\n✅ Generated ${totalBlocks} test cases from ${fileResults.length} files`)
|
||||||
|
console.log(`📝 Output: ${outputFile}`)
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import fs from 'node:fs'
|
||||||
|
import path from 'node:path'
|
||||||
|
import { glob } from 'glob'
|
||||||
|
|
||||||
|
const docsDir = path.resolve('packages/artplayer-vitepress/docs')
|
||||||
|
|
||||||
|
function fixMarkdownFile(filePath) {
|
||||||
|
const content = fs.readFileSync(filePath, 'utf-8')
|
||||||
|
const lines = content.split('\n')
|
||||||
|
const fixedLines = []
|
||||||
|
let inCodeBlock = false
|
||||||
|
let fixes = 0
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i]
|
||||||
|
|
||||||
|
// Check if entering a code block
|
||||||
|
if (line.startsWith('```') && !inCodeBlock) {
|
||||||
|
inCodeBlock = true
|
||||||
|
fixedLines.push(line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if properly exiting a code block
|
||||||
|
if (line.startsWith('```') && inCodeBlock) {
|
||||||
|
inCodeBlock = false
|
||||||
|
fixedLines.push(line)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we hit a heading while still in a code block (missing ```)
|
||||||
|
if (inCodeBlock && line.startsWith('## ')) {
|
||||||
|
// Add the missing closing ```
|
||||||
|
fixedLines.push('```')
|
||||||
|
fixedLines.push('')
|
||||||
|
inCodeBlock = false
|
||||||
|
fixes++
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we hit ::: (admonition) while still in a code block
|
||||||
|
if (inCodeBlock && line.startsWith(':::')) {
|
||||||
|
fixedLines.push('```')
|
||||||
|
fixedLines.push('')
|
||||||
|
inCodeBlock = false
|
||||||
|
fixes++
|
||||||
|
}
|
||||||
|
|
||||||
|
fixedLines.push(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// If file ended while still in code block
|
||||||
|
if (inCodeBlock) {
|
||||||
|
fixedLines.push('```')
|
||||||
|
fixes++
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fixes > 0) {
|
||||||
|
fs.writeFileSync(filePath, fixedLines.join('\n'))
|
||||||
|
console.log(`✅ Fixed ${fixes} code blocks in ${path.relative(docsDir, filePath)}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return fixes
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find all markdown files
|
||||||
|
const files = glob.sync('**/*.md', { cwd: docsDir, absolute: true })
|
||||||
|
|
||||||
|
let totalFixes = 0
|
||||||
|
for (const file of files) {
|
||||||
|
totalFixes += fixMarkdownFile(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`\n✨ Total: Fixed ${totalFixes} code blocks in ${files.length} files`)
|
||||||
Reference in new issue
Block a user