mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
test(ambilight): [PKG-AMBILIGHT-01] freeze actual release and invocation contracts
This commit is contained in:
1 parent
c57c7e4b16
commit
06032a6906
17 files changed
+638
-7
No files matched your search
@@ -0,0 +1,43 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { execFileSync } from 'node:child_process'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { archiveFiles, ensureArchive, hash, readMember, refactorDir } from './releases.mjs'
|
||||
|
||||
export async function verifyAmbilightContract() {
|
||||
const baseline = JSON.parse(fs.readFileSync(path.join(refactorDir, 'baselines/ambilight-release.json'), 'utf8'))
|
||||
const archives = new Map()
|
||||
for (const release of [baseline.release, ...baseline.previous]) {
|
||||
const archive = await ensureArchive(release)
|
||||
assert.deepEqual(archiveFiles(archive), Object.keys(release.files).sort())
|
||||
for (const [file, expected] of Object.entries(release.files))
|
||||
assert.equal(hash(readMember(archive, file)), expected, `${release.version}/${file}`)
|
||||
assert.deepEqual(JSON.parse(readMember(archive, 'package/package.json')), release.manifest)
|
||||
for (const field of ['main', 'module', 'types', 'legacy']) {
|
||||
const entry = release.manifest[field]
|
||||
if (entry)
|
||||
assert(Object.hasOwn(release.files, `package/${entry.replace(/^\.\//, '')}`))
|
||||
}
|
||||
if (release.historicalCore) {
|
||||
const core = release.historicalCore
|
||||
const content = execFileSync('git', ['show', `${core.commit}:${core.file}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(content), core.sha256LF)
|
||||
assert.equal(JSON.parse(content).version, core.version)
|
||||
}
|
||||
archives.set(release.version, archive)
|
||||
}
|
||||
const sources = new Map()
|
||||
for (const [file, expected] of Object.entries(baseline.source)) {
|
||||
const content = execFileSync('git', ['show', `${baseline.sourceCommit}:${file}`], { encoding: 'utf8' }).replaceAll('\r\n', '\n')
|
||||
assert.equal(hash(content), expected, `Ambilight frozen source: ${file}`)
|
||||
sources.set(file, content)
|
||||
}
|
||||
return { baseline, archives, sources }
|
||||
}
|
||||
|
||||
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
||||
const { baseline } = await verifyAmbilightContract()
|
||||
console.log(`Ambilight verified: ${[baseline.release, ...baseline.previous].map(release => release.version).join(', ')}; 12 members, frozen workspace and Git core associations`)
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import assert from 'node:assert/strict'
|
||||
// eslint-disable-next-line test/no-import-node-test -- Freeze actual published plugin contracts before migration.
|
||||
import test from 'node:test'
|
||||
import vm from 'node:vm'
|
||||
import { ambilightEnvironment, ambilightHistorical } from '../../test/helpers/ambilight.js'
|
||||
import { verifyAmbilightContract } from './ambilight-contract.mjs'
|
||||
import { readMember } from './releases.mjs'
|
||||
|
||||
const contract = await verifyAmbilightContract()
|
||||
|
||||
test('Ambilight archives, manifests and source snapshots retain their exact identities', () => {
|
||||
assert.equal(contract.baseline.release.version, '1.1.0')
|
||||
assert.equal(contract.baseline.previous[0].version, '1.0.0')
|
||||
assert.equal([...contract.archives].length, 2)
|
||||
assert.equal(contract.baseline.release.historicalCore.version, '5.3.1')
|
||||
assert.equal(contract.baseline.previous[0].historicalCore.version, '5.1.7')
|
||||
})
|
||||
|
||||
test('Ambilight published CommonJS and script globals preserve their distinct export shapes', () => {
|
||||
for (const release of [contract.baseline.release, ...contract.baseline.previous]) {
|
||||
for (const field of ['main', 'legacy']) {
|
||||
const code = readMember(contract.archives.get(release.version), `package/${release.manifest[field].replace(/^\.\//, '')}`).toString()
|
||||
const module = { exports: {} }
|
||||
const window = {}
|
||||
vm.runInNewContext(code, { module, exports: module.exports, window }, { timeout: 5000 })
|
||||
assert.equal(typeof module.exports, release.version === '1.0.0' ? 'object' : 'function')
|
||||
assert.equal(typeof (module.exports.default || module.exports)(), 'function')
|
||||
const global = { window: {} }
|
||||
vm.runInNewContext(code, global, { timeout: 5000 })
|
||||
assert.equal(typeof (global.artplayerPluginAmbilight || global.window.artplayerPluginAmbilight), 'function')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('Ambilight published declarations retain the required options argument and ignored zIndex field', () => {
|
||||
const old = readMember(contract.archives.get('1.0.0'), 'package/types/artplayer-plugin-ambilight.d.ts').toString()
|
||||
const current = readMember(contract.archives.get('1.1.0'), 'package/types/artplayer-plugin-ambilight.d.ts').toString()
|
||||
assert.match(old, /export = artplayerPluginAmbilight/)
|
||||
assert.match(current, /export default artplayerPluginAmbilight/)
|
||||
for (const source of [old, current]) {
|
||||
assert.match(source, /\(option: Option\)/)
|
||||
assert.match(source, /zIndex\??: number/)
|
||||
}
|
||||
assert.match(current, /blur\?: string/)
|
||||
assert.match(old, /blur: string/)
|
||||
})
|
||||
|
||||
test('Ambilight 1.1.0 native ESM import exposes the default factory', async () => {
|
||||
const source = readMember(contract.archives.get('1.1.0'), 'package/dist/artplayer-plugin-ambilight.mjs').toString()
|
||||
const namespace = await import(`data:text/javascript,${encodeURIComponent(source)}`)
|
||||
assert.deepEqual(Object.keys(namespace), ['default'])
|
||||
assert.equal(typeof namespace.default, 'function')
|
||||
assert.equal(typeof namespace.default(), 'function')
|
||||
})
|
||||
|
||||
for (const implementation of await ambilightHistorical()) {
|
||||
test(`Ambilight ${implementation.name}: defaults, option-read timing, styling, grid sampling and public returns`, async () => {
|
||||
const env = await ambilightEnvironment(implementation)
|
||||
const option = { opacity: 0.1, zIndex: -99 }
|
||||
const attach = env.factory(option)
|
||||
option.opacity = 0.7
|
||||
const result = attach(env.art)
|
||||
const element = env.parent.children[0]
|
||||
assert.equal(element.className, 'artplayer-plugin-ambilight')
|
||||
assert.equal(element.children.length, 9)
|
||||
assert.equal(element.style.zIndex, 9, 'Historical zIndex option is ignored')
|
||||
assert.equal(element.children[0].style.opacity, 0.7)
|
||||
assert.equal(element.children[0].style.filter, 'blur(50px)')
|
||||
assert.equal(element.children[0].style.transition, 'background-color 0.3s ease')
|
||||
assert.deepEqual(Object.keys(result), ['name', 'start', 'stop'])
|
||||
assert.equal(result.name, 'artplayerPluginAmbilight')
|
||||
assert.equal(result.start(), undefined)
|
||||
assert.equal(env.frames.size, 1)
|
||||
assert.equal(env.draws.length, 0)
|
||||
env.art.playing = true
|
||||
env.frame(100)
|
||||
assert.equal(env.draws.length, 9)
|
||||
assert.deepEqual([...env.draws[0].slice(1)], [0, 0, 100, 50, 0, 0, 1, 1])
|
||||
assert.deepEqual([...env.draws[8].slice(1)], [200, 100, 100, 50, 0, 0, 1, 1])
|
||||
assert.equal(element.children[8].style.backgroundColor, 'rgb(9, 20, 30)')
|
||||
assert.equal(result.stop(), undefined)
|
||||
assert.equal(env.frames.size, 0)
|
||||
assert.equal(typeof env.factory(), 'function', 'Runtime accepts omitted options despite the old declaration')
|
||||
})
|
||||
}
|
||||
@@ -44,7 +44,7 @@ function fixture(t) {
|
||||
test('Actual contract model assigns all 264 family rows and separates exact published versions from workspace snapshots', () => {
|
||||
assert.equal(actual.policy.packages.length, 22)
|
||||
assert.equal(actual.families.length, 12)
|
||||
assert.equal(actual.policy.versions.filter(version => version.kind === 'published-baseline').length, 7)
|
||||
assert.equal(actual.policy.versions.filter(version => version.kind === 'published-baseline').length, 9)
|
||||
assert.equal(actual.policy.versions.filter(version => version.kind === 'workspace-baseline').length, 22)
|
||||
assert.equal(actual.policy.cases.length, 10)
|
||||
const markdown = renderContracts(actual)
|
||||
|
||||
Reference in new issue
Block a user