forked from Zakaria/hermes-agent
Hermes-agent
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
'use strict'
|
||||
|
||||
const assert = require('node:assert')
|
||||
const test = require('node:test')
|
||||
|
||||
const { __testing, extractThemes, readCentralDirectory } = require('./vscode-marketplace.cjs')
|
||||
|
||||
// Build a minimal zip with stored (uncompressed) entries so the test controls
|
||||
// the bytes exactly — exercises the central-directory reader + theme extraction
|
||||
// without a deflate dependency.
|
||||
function makeZip(entries) {
|
||||
const locals = []
|
||||
const centrals = []
|
||||
let offset = 0
|
||||
|
||||
for (const { name, data } of entries) {
|
||||
const nameBuf = Buffer.from(name, 'utf8')
|
||||
const body = Buffer.from(data, 'utf8')
|
||||
|
||||
const local = Buffer.alloc(30 + nameBuf.length)
|
||||
local.writeUInt32LE(0x04034b50, 0)
|
||||
local.writeUInt16LE(0, 8) // method: stored
|
||||
local.writeUInt32LE(body.length, 18) // compressed size
|
||||
local.writeUInt32LE(body.length, 22) // uncompressed size
|
||||
local.writeUInt16LE(nameBuf.length, 26)
|
||||
nameBuf.copy(local, 30)
|
||||
|
||||
locals.push(local, body)
|
||||
|
||||
const central = Buffer.alloc(46 + nameBuf.length)
|
||||
central.writeUInt32LE(0x02014b50, 0)
|
||||
central.writeUInt16LE(0, 10) // method: stored
|
||||
central.writeUInt32LE(body.length, 20)
|
||||
central.writeUInt32LE(body.length, 24)
|
||||
central.writeUInt16LE(nameBuf.length, 28)
|
||||
central.writeUInt32LE(offset, 42) // local header offset
|
||||
nameBuf.copy(central, 46)
|
||||
|
||||
centrals.push(central)
|
||||
offset += local.length + body.length
|
||||
}
|
||||
|
||||
const centralStart = offset
|
||||
const centralBuf = Buffer.concat(centrals)
|
||||
|
||||
const eocd = Buffer.alloc(22)
|
||||
eocd.writeUInt32LE(0x06054b50, 0)
|
||||
eocd.writeUInt16LE(entries.length, 8)
|
||||
eocd.writeUInt16LE(entries.length, 10)
|
||||
eocd.writeUInt32LE(centralBuf.length, 12)
|
||||
eocd.writeUInt32LE(centralStart, 16)
|
||||
|
||||
return Buffer.concat([...locals, centralBuf, eocd])
|
||||
}
|
||||
|
||||
test('readCentralDirectory finds every entry', () => {
|
||||
const zip = makeZip([
|
||||
{ name: 'extension/package.json', data: '{}' },
|
||||
{ name: 'extension/themes/x.json', data: '{}' }
|
||||
])
|
||||
|
||||
const records = readCentralDirectory(zip)
|
||||
assert.ok(records.has('extension/package.json'))
|
||||
assert.ok(records.has('extension/themes/x.json'))
|
||||
})
|
||||
|
||||
test('extractThemes reads contributed color themes (resolving ./ paths)', () => {
|
||||
const pkg = JSON.stringify({
|
||||
name: 'theme-dracula',
|
||||
displayName: 'Dracula',
|
||||
contributes: {
|
||||
themes: [{ label: 'Dracula', uiTheme: 'vs-dark', path: './themes/dracula.json' }]
|
||||
}
|
||||
})
|
||||
const themeJson = JSON.stringify({ name: 'Dracula', type: 'dark', colors: { 'editor.background': '#282a36' } })
|
||||
|
||||
const zip = makeZip([
|
||||
{ name: 'extension/package.json', data: pkg },
|
||||
{ name: 'extension/themes/dracula.json', data: themeJson }
|
||||
])
|
||||
|
||||
const themes = extractThemes(zip)
|
||||
assert.strictEqual(themes.length, 1)
|
||||
assert.strictEqual(themes[0].label, 'Dracula')
|
||||
assert.strictEqual(themes[0].uiTheme, 'vs-dark')
|
||||
assert.match(themes[0].contents, /editor\.background/)
|
||||
})
|
||||
|
||||
test('extractThemes returns empty when the extension contributes no themes', () => {
|
||||
const zip = makeZip([{ name: 'extension/package.json', data: JSON.stringify({ name: 'x', contributes: {} }) }])
|
||||
assert.deepStrictEqual(extractThemes(zip), [])
|
||||
})
|
||||
|
||||
test('extractThemes throws when the manifest is missing', () => {
|
||||
const zip = makeZip([{ name: 'extension/other.txt', data: 'hi' }])
|
||||
assert.throws(() => extractThemes(zip), /manifest missing/i)
|
||||
})
|
||||
|
||||
test('looksLikeIconTheme filters icon/product-icon packs out of theme search', () => {
|
||||
const { looksLikeIconTheme } = __testing
|
||||
|
||||
// Tagged contribution points are the strongest signal.
|
||||
assert.strictEqual(looksLikeIconTheme({ tags: ['theme', 'icon-theme'] }), true)
|
||||
assert.strictEqual(looksLikeIconTheme({ tags: ['product-icon-theme'] }), true)
|
||||
|
||||
// Name/description fallback for packs that don't tag themselves.
|
||||
assert.strictEqual(looksLikeIconTheme({ displayName: 'Material Icon Theme' }), true)
|
||||
assert.strictEqual(looksLikeIconTheme({ shortDescription: 'A pack of file icons.' }), true)
|
||||
|
||||
// Real color themes survive.
|
||||
assert.strictEqual(looksLikeIconTheme({ displayName: 'Dracula Official', tags: ['theme', 'color-theme'] }), false)
|
||||
assert.strictEqual(looksLikeIconTheme({ displayName: 'One Dark Pro' }), false)
|
||||
})
|
||||
Reference in New Issue
Block a user