154 lines
4.2 KiB
JavaScript
154 lines
4.2 KiB
JavaScript
import { readFile } from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import test from 'brittle'
|
|
import b4a from 'b4a'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor
|
|
|
|
async function loadAppstoreBin() {
|
|
const runtime = await readFile(path.join(__dirname, '../lib/runtime.js'), 'utf8')
|
|
const p2p = await readFile(path.join(__dirname, '../lib/p2p-suite.js'), 'utf8')
|
|
const pear = await readFile(path.join(__dirname, '../lib/appstore-pear.js'), 'utf8')
|
|
const body = await readFile(path.join(__dirname, '../src/appstore.js'), 'utf8')
|
|
return new AsyncFunction(
|
|
'ctx',
|
|
'argv',
|
|
`${runtime}\n${p2p}\n${pear}\n${body}\nif (typeof run === 'function') return await run(ctx, argv)\n`
|
|
)
|
|
}
|
|
|
|
function mkMemVfs(initial = {}) {
|
|
/** @type {Map<string, Uint8Array>} */
|
|
const files = new Map(Object.entries(initial))
|
|
return {
|
|
files,
|
|
async mkdir() {},
|
|
async readdir(p) {
|
|
const prefix = p.endsWith('/') ? p : p + '/'
|
|
const names = new Set()
|
|
for (const key of files.keys()) {
|
|
if (!key.startsWith(prefix)) continue
|
|
names.add(key.slice(prefix.length).split('/')[0])
|
|
}
|
|
return [...names].filter(Boolean)
|
|
},
|
|
async stat(p) {
|
|
if (!files.has(p)) {
|
|
for (const key of files.keys()) {
|
|
if (key.startsWith(p + '/')) return { isDirectory: true, type: 'directory' }
|
|
}
|
|
throw new Error('ENOENT')
|
|
}
|
|
return { isDirectory: false, type: 'file' }
|
|
},
|
|
async readFile(p) {
|
|
if (!files.has(p)) throw new Error('ENOENT ' + p)
|
|
return files.get(p)
|
|
},
|
|
async writeFile(p, buf) {
|
|
files.set(p, buf instanceof Uint8Array ? buf : new Uint8Array(buf))
|
|
}
|
|
}
|
|
}
|
|
|
|
test('appstore install fetches pear tree from local HDMS mount', async (t) => {
|
|
const key = '8wdec11bcygidig1qubkuexgfjw57we5whgcsbsajao73g9eagry'
|
|
const mount = '/mnt/pear-my-pear-app'
|
|
const home = '/home/guest'
|
|
const vfs = mkMemVfs({
|
|
[`${mount}/sources/index.js`]: b4a.from('console.log("Hello from my Pear app!");\n', 'utf8'),
|
|
[`${mount}/package.json`]: b4a.from(
|
|
JSON.stringify({ name: 'my-pear-app', main: 'index.js', version: '0.1.0' }),
|
|
'utf8'
|
|
)
|
|
})
|
|
|
|
const hdms = {
|
|
active: true,
|
|
byLabel: new Map([
|
|
[
|
|
'pear-my-pear-app',
|
|
{
|
|
drive: {},
|
|
entry: { label: 'pear-my-pear-app', key, mode: 'writable' }
|
|
}
|
|
]
|
|
]),
|
|
registry: { version: 1, drives: [{ label: 'pear-my-pear-app', key, mode: 'writable' }] }
|
|
}
|
|
|
|
const logs = []
|
|
const ctx = {
|
|
vfs,
|
|
b4a,
|
|
env: { HOME: home },
|
|
identity: { state: 'unlocked' },
|
|
disk: { hdmsController: hdms },
|
|
console: {
|
|
log(...a) {
|
|
logs.push(a.join(' '))
|
|
},
|
|
error() {},
|
|
warn() {}
|
|
}
|
|
}
|
|
|
|
const run = await loadAppstoreBin()
|
|
await run(ctx, [
|
|
'appstore',
|
|
'install',
|
|
'my-pear-app',
|
|
`pear://0.10.${key}`,
|
|
'--yes'
|
|
])
|
|
|
|
const pkgDir = `${home}/.appstore/packages/my-pear-app`
|
|
t.ok(vfs.files.has(`${pkgDir}/sources/index.js`))
|
|
t.ok(vfs.files.has(`${pkgDir}/manifest.json`))
|
|
t.ok(logs.some((l) => l.includes('fetched: 2 file')))
|
|
})
|
|
|
|
test('appstore launch runs materialized entry script', async (t) => {
|
|
const home = '/home/guest'
|
|
const pkgDir = `${home}/.appstore/packages/my-pear-app`
|
|
const vfs = mkMemVfs({
|
|
[`${home}/.appstore/registry.json`]: b4a.from(
|
|
JSON.stringify({
|
|
schema: 1,
|
|
packages: [
|
|
{
|
|
name: 'my-pear-app',
|
|
pearLink: 'pear://abc',
|
|
type: 'app'
|
|
}
|
|
]
|
|
}),
|
|
'utf8'
|
|
),
|
|
[`${pkgDir}/sources/index.js`]: b4a.from('console.log("Hello from my Pear app!");\n', 'utf8'),
|
|
[`${pkgDir}/package.json`]: b4a.from(JSON.stringify({ main: 'index.js' }), 'utf8')
|
|
})
|
|
|
|
const logs = []
|
|
const ctx = {
|
|
vfs,
|
|
b4a,
|
|
env: { HOME: home },
|
|
console: {
|
|
log(...a) {
|
|
logs.push(a.join(' '))
|
|
},
|
|
error() {},
|
|
warn() {}
|
|
}
|
|
}
|
|
|
|
const run = await loadAppstoreBin()
|
|
await run(ctx, ['appstore', 'launch', 'my-pear-app'])
|
|
|
|
t.ok(logs.some((l) => l.includes('Hello from my Pear app!')))
|
|
t.ok(logs.some((l) => l.includes('Launched "my-pear-app"')))
|
|
})
|