OverviewFilesCommitsIssuesDocsReleasesPeers

favela-surface-android / test / boundary.test.js

57 lines · javascript ref:
// The worklet must not reach the PROTOTYPE'S UI.
//
// ⛔ REVERSED DELIBERATELY, 2026-09-10. This file used to forbid the whole atproto stack, on the
// reading that this repo existed to be free of it. That reading is wrong: favela-android was the
// PROTOTYPE and this is the full-stack app, so hyper-proto-peer belongs here — the phone holds its
// own DID key and signs its own repo, which is the entire point of a full node.
//
// ⛔ WHAT STILL MUST NOT COME BACK IS `favela-web`. It is the prototype's renderer and favela-surface
// replaces it; importing it would mean two UIs over one node, which is the duplication this repo was
// actually created to end (#45 measured the alternative at 1,771 lines of render.js plus 715 lines
// of React Native built and reversed in four days).
//
// ⚠ Checks IMPORTS rather than mentions, static AND dynamic — favela-android's coupling took the
// dynamic form through nine `import()` calls, which a static reading misses entirely. The prose in
// these files discusses favela-web constantly and should.

import test from 'brittle'
import fs from 'bare-fs'
import { join } from 'bare-path'

const ROOT = new URL('..', import.meta.url).pathname
const FORBIDDEN = /(favela-web)/

const walk = (dir) => fs.readdirSync(dir, { withFileTypes: true }).flatMap((e) =>
  e.name === 'node_modules' ? []
    : e.isDirectory() ? walk(join(dir, e.name))
      : /\.(js|jsx)$/.test(e.name) ? [join(dir, e.name)] : [])

// Every import, static or dynamic. `import('x')` is the form favela-android's coupling actually took.
const importsOf = (src) => [
  ...src.matchAll(/(?:from|import)\s*\(?\s*['"]([^'"]+)['"]/g)
].map((m) => m[1])

test('★ no source file imports the prototype UI — static OR dynamic', (t) => {
  for (const f of [...walk(join(ROOT, 'lib')), ...walk(join(ROOT, 'app'))]) {
    for (const spec of importsOf(fs.readFileSync(f, 'utf8'))) {
      t.absent(FORBIDDEN.test(spec), f.slice(ROOT.length) + ' imports ' + spec)
    }
  }
})

test('and neither does a dependency', (t) => {
  const pkg = JSON.parse(fs.readFileSync(join(ROOT, 'package.json'), 'utf8'))
  for (const d of Object.keys({ ...pkg.dependencies, ...pkg.devDependencies })) {
    t.absent(FORBIDDEN.test(d), d + ' is not a dependency of this app')
  }
})

test('⚠ the check is on IMPORTS, not mentions — the prose must stay free to explain', (t) => {
  // A mention-based check would fail this repo immediately and correctly: every design decision here
  // is explained by reference to what favela-android did. Losing that prose to satisfy a grep would
  // be a bad trade, so the boundary is drawn where the coupling actually lives.
  const src = fs.readFileSync(join(ROOT, 'lib/node.js'), 'utf8')
  t.ok(/favela-android|hyper-proto-peer|favela-web/.test(src), 'the file does discuss them')
  t.absent(importsOf(src).some((s) => FORBIDDEN.test(s)), 'and imports none of them')
})