Skip to content

tests: inital framework #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Feb 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ jobs:

- uses: actions/setup-node@v3
with:
node-version: '18.x'
node-version: '20'
corepack-enable: true
registry-url: 'https://registry.npmjs.org'

- name: Deps
run: |
npm i -g corepack@latest
corepack enable
pnpm i --frozen-lockfile

- name: Test
run: pnpm -r test
run: pnpm test:ci
1 change: 1 addition & 0 deletions adex/.snapshots/0f704ada2712880ee7394b0fc9b10abf/0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"\n <!doctype html>\n <html lang=\"\">\n <head>\n <script type=\"module\" src=\"/@vite/client\"></script>\n\n <meta charset=\"UTF-8\" />\n \n <title></title>\n\n \n \n \n </head>\n <body>\n <div id=\"app\"><h1 class=\"text-red-500\">Hello World</h1></div>\n <script type='module' src=\"/virtual:adex:client\"></script></body>\n </html>\n "
1 change: 1 addition & 0 deletions adex/.snapshots/0f704ada2712880ee7394b0fc9b10abf/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"\n <!doctype html>\n <html lang=\"\">\n <head>\n <script type=\"module\" src=\"/@vite/client\"></script>\n\n <meta charset=\"UTF-8\" />\n \n <title></title>\n\n \n \n \n </head>\n <body>\n <div id=\"app\"><h2>About</h2></div>\n <script type='module' src=\"/virtual:adex:client\"></script></body>\n </html>\n "
1 change: 1 addition & 0 deletions adex/.snapshots/dd4c9d1ee8f7b693c42e503acab1a0c0/0.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"\n <!doctype html>\n <html lang=\"\">\n <head>\n <script type=\"module\" src=\"/@vite/client\"></script>\n\n <meta charset=\"UTF-8\" />\n \n <title></title>\n\n \n \n \n </head>\n <body>\n <div id=\"app\"><h1>Hello World</h1></div>\n <script type='module' src=\"/virtual:adex:client\"></script></body>\n </html>\n "
1 change: 1 addition & 0 deletions adex/.snapshots/dd4c9d1ee8f7b693c42e503acab1a0c0/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"\n <!doctype html>\n <html lang=\"\">\n <head>\n <script type=\"module\" src=\"/@vite/client\"></script>\n\n <meta charset=\"UTF-8\" />\n \n <title></title>\n\n \n \n \n </head>\n <body>\n <div id=\"app\"><h2>About</h2></div>\n <script type='module' src=\"/virtual:adex:client\"></script></body>\n </html>\n "
1 change: 1 addition & 0 deletions adex/.snapshots/dd4c9d1ee8f7b693c42e503acab1a0c0/2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"import { createHotContext as __vite__createHotContext } from \"/@vite/client\";import.meta.hot = __vite__createHotContext(\"/@id/__x00__virtual:adex:global.css\");import { updateStyle as __vite__updateStyle, removeStyle as __vite__removeStyle } from \"/@vite/client\"\nconst __vite__id = \"\\u0000virtual:adex:global.css\"\nconst __vite__css = \"\"\n__vite__updateStyle(__vite__id, __vite__css)\nimport.meta.hot.accept()\nimport.meta.hot.prune(() => __vite__removeStyle(__vite__id))"
6 changes: 5 additions & 1 deletion adex/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
"runtime"
],
"scripts": {
"next": "bumpp"
"next": "bumpp",
"test": "glob -c 'node --test' tests/**/*.spec.js"
},
"dependencies": {
"@barelyhuman/tiny-use": "^0.0.2",
Expand All @@ -77,10 +78,13 @@
"unifont": "^0.0.2"
},
"devDependencies": {
"@matteo.collina/snap": "^0.3.0",
"@preact/preset-vite": "^2.8.2",
"@types/node": "^20.14.10",
"adex-adapter-node": "^0.0.17",
"autoprefixer": "^10.4.19",
"glob": "^11.0.1",
"kolorist": "^1.8.0",
"tailwindcss": "^3.4.4",
"vite": "^5.3.1"
},
Expand Down
12 changes: 3 additions & 9 deletions adex/runtime/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,6 @@ import 'virtual:adex:global.css'
// @ts-expect-error injected by vite
import { routes } from '~routes'

const withComponents = routes.map(d => {
return {
...d,
component: lazy(d.module),
}
})

function ComponentWrapper({ url = '' }) {
return h(
LocationProvider,
Expand All @@ -31,8 +24,8 @@ function ComponentWrapper({ url = '' }) {
h(
Router,
{},
withComponents.map(d =>
h(Route, { path: d.routePath, component: d.component })
routes.map(d =>
h(Route, { path: d.routePath, component: lazy(d.module) })
)
)
)
Expand All @@ -46,6 +39,7 @@ export const App = ({ url = '' }) => {
async function hydrate() {
preactHydrate(h(ComponentWrapper, {}), document.getElementById('app'))
}

if (typeof window !== 'undefined') {
hydrate()
}
8 changes: 3 additions & 5 deletions adex/runtime/handler.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CONSTANTS, emitToHooked } from 'adex/hook'
import { prepareRequest, prepareResponse } from 'adex/http'
import { toStatic } from 'adex/ssr'
import { renderToString } from 'adex/utils/isomorphic'
import { renderToStringAsync } from 'adex/utils/isomorphic'
import { h } from 'preact'

// @ts-expect-error injected by vite
Expand Down Expand Up @@ -60,9 +60,7 @@ export async function handler(req, res) {
// @ts-expect-error
global.location = new URL(req.url, 'http://localhost')

const rendered = await renderToString(
h(App, { url: [baseURL, search].filter(Boolean).join('?') })
)
const rendered = await renderToStringAsync(h(App, { url: req.url }), {})

const htmlString = HTMLTemplate({
metas,
Expand All @@ -73,7 +71,7 @@ export async function handler(req, res) {
routeParams: Buffer.from(JSON.stringify(routeParams), 'utf8').toString(
'base64'
),
body: rendered.html,
body: rendered,
})
const modifiableContext = {
req: req,
Expand Down
2 changes: 1 addition & 1 deletion adex/src/head.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type {
export {
useHead,
useLang,
useLink,
Expand Down
2 changes: 1 addition & 1 deletion adex/src/utils/isomorphic.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { parse as pathToRegex } from 'regexparam'
export { prerender as renderToString } from 'preact-iso'
export { renderToStringAsync } from 'preact-render-to-string'
69 changes: 67 additions & 2 deletions adex/src/vite.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,71 @@ export function adex({
'virtual:adex:handler',
readFileSync(join(__dirname, '../runtime/handler.js'), 'utf8')
),
createVirtualModule(
'virtual:adex:server',
`import { createServer } from '${adapterMap[adapter]}'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { existsSync, readFileSync } from 'node:fs'
import { env } from 'adex/env'

import 'virtual:adex:font.css'
import 'virtual:adex:global.css'

const __dirname = dirname(fileURLToPath(import.meta.url))

const PORT = parseInt(env.get('PORT', '3000'), 10)
const HOST = env.get('HOST', 'localhost')

const paths = {
assets: join(__dirname, './assets'),
islands: join(__dirname, './islands'),
client: join(__dirname, '../client'),
}

function getServerManifest() {
const manifestPath = join(__dirname, 'manifest.json')
if (existsSync(manifestPath)) {
const manifestFile = readFileSync(manifestPath, 'utf8')
return parseManifest(manifestFile)
}
return {}
}

function getClientManifest() {
const manifestPath = join(__dirname, '../client/manifest.json')
if (existsSync(manifestPath)) {
const manifestFile = readFileSync(manifestPath, 'utf8')
return parseManifest(manifestFile)
}
return {}
}

function parseManifest(manifestString) {
try {
const manifestJSON = JSON.parse(manifestString)
return manifestJSON
} catch (err) {
return {}
}
}

const server = createServer({
port: PORT,
host: HOST,
adex:{
manifests:{server:getServerManifest(),client:getClientManifest()},
paths,
}
})

if ('run' in server) {
server.run()
}

export default server.fetch
`
),
addFontsPlugin(fonts),
adexDevServer({ islands }),
adexBuildPrep({ islands }),
Expand Down Expand Up @@ -176,7 +241,7 @@ function adexIslandsBuilder() {
// if being imported by the client, don't send
// back the transformed server code, send the
// original component
if (!viteEnv.ssr) return
if (!viteEnv?.ssr) return

const islands = findIslands(readSourceFile(id), {
isFunctionIsland: node =>
Expand Down Expand Up @@ -655,7 +720,7 @@ function adexGuards() {

// ignore usage of `process.env` in `adex/env`
const envLoadId = await this.resolve('adex/env')
if (id === envLoadId.id) return
if (id === envLoadId?.id) return

if (code.includes('process.env')) {
this.error(
Expand Down
6 changes: 6 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions":{
"jsx":"react-jsx",
"jsxImportSource": "preact"
}
}
14 changes: 14 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "minimal-tailwind",
"type": "module",
"dependencies": {
"@preact/preset-vite": "catalog:",
"adex": "workspace:*",
"preact": "catalog:"
},
"devDependencies": {
"autoprefixer": "^10.4.20",
"tailwindcss": "^3",
"vite": "^5.4.8"
}
}
6 changes: 6 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
3 changes: 3 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/src/global.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
3 changes: 3 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/src/pages/about.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function AboutPage() {
return <h2>About</h2>
}
3 changes: 3 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/src/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <h1 class="text-red-500">Hello World</h1>
}
8 changes: 8 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/pages/**/*.{tsx,jsx}'],
theme: {
extend: {},
},
plugins: [],
}
13 changes: 13 additions & 0 deletions adex/tests/fixtures/minimal-tailwind/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'vite'
import { adex } from "adex"
import preact from "@preact/preset-vite"

export default defineConfig({
plugins: [
adex({
islands: false,
ssr: true,
}),
preact(),
],
})
6 changes: 6 additions & 0 deletions adex/tests/fixtures/minimal/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"compilerOptions":{
"jsx":"react-jsx",
"jsxImportSource": "preact"
}
}
14 changes: 14 additions & 0 deletions adex/tests/fixtures/minimal/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "minimal",
"type": "module",
"dependencies": {
"adex": "workspace:*",
"preact": "catalog:",
"@preact/preset-vite": "catalog:"
},

"devDependencies": {
"vite": "^5.4.8"
}

}
3 changes: 3 additions & 0 deletions adex/tests/fixtures/minimal/src/pages/about.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function AboutPage() {
return <h2>About</h2>
}
3 changes: 3 additions & 0 deletions adex/tests/fixtures/minimal/src/pages/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Page() {
return <h1>Hello World</h1>
}
13 changes: 13 additions & 0 deletions adex/tests/fixtures/minimal/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { defineConfig } from 'vite'
import { adex } from "adex"
import preact from "@preact/preset-vite"

export default defineConfig({
plugins: [
adex({
islands: false,
ssr: true,
}),
preact(),
],
})
37 changes: 37 additions & 0 deletions adex/tests/minimal-tailwind.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Snap from '@matteo.collina/snap'
import { after, before, describe, it } from 'node:test'
import assert, { deepEqual } from 'node:assert'

import { devServerURL, launchDemoDevServer } from './utils.js'
const snap = Snap(import.meta.url)

describe('devMode ssr minimal with styles', async () => {
let devServerProc
before(async () => {
devServerProc = await launchDemoDevServer('tests/fixtures/minimal-tailwind')
})
after(async () => {
devServerProc.kill()
})

await it('gives a non-static ssr response', async ctx => {
const response = await fetch(devServerURL).then(d => d.text())
const snapshot = await snap(response)
deepEqual(response, snapshot)
})

await it('gives a static SSR response', async ctx => {
const response2 = await fetch(new URL('/about', devServerURL)).then(d =>
d.text()
)
const snapshot = await snap(response2)
deepEqual(response2, snapshot)
})

await it('has styles', async ctx => {
const response = await fetch(
new URL('/virtual:adex:global.css', devServerURL)
).then(d => d.text())
assert.ok(response.includes('.text-red-500'))
})
})
Loading
Loading