Skip to content

Commit

Permalink
Fix Windows CI via node+jest (as alternative to bun)
Browse files Browse the repository at this point in the history
  • Loading branch information
fritx committed Jan 15, 2024
1 parent 3cf395b commit 2ce6b77
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 37 deletions.
26 changes: 25 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,35 @@ on:

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
env:
- { os: 'ubuntu-22.04', tool: 'bun' }
- { os: 'macos-12', tool: 'bun' }
# Windows support for bun install is not implemented yet
# - { os: 'windows-2022', tool: 'bun' }
# - { os: 'ubuntu-22.04', tool: 'node+jest' }
# - { os: 'macos-12', tool: 'node+jest' }
- { os: 'windows-2022', tool: 'node+jest' }
runs-on: ${{ matrix.env.os }}
steps:
- uses: actions/checkout@v3

# Testing `bun`
- uses: oven-sh/setup-bun@v1
if: ${{ matrix.env.tool == 'bun' }}
- run: |
bun -v
bun install
bun install --no-save esbuild@^0.19.11
bun test --coverage
if: ${{ matrix.env.tool == 'bun' }}
# Testing `node+jest`
- run: |
node -v && npm -v
npm install
npm install --no-save jest jest-extended esbuild@^0.19.11
# https://jestjs.io/docs/ecmascript-modules
node --experimental-vm-modules node_modules/jest/bin/jest --runInBand --coverage
if: ${{ matrix.env.tool == 'node+jest' }}
Binary file modified bun.lockb
Binary file not shown.
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@
"version": "0.0.0",
"private": true,
"license": "MIT",

"workspaces": [
"packages/*"
],

"engines": {
"bun": ">=1",
"node": ">=18"
},
"jest": {
"setupFilesAfterEnv": ["jest-extended/all"]
}
}
15 changes: 12 additions & 3 deletions packages/nuejs/test/render.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,18 @@ test('{ expr } error', () => {
render('<div>\n<b>Hey { foo[0] } { title }</b></div>')

} catch (e) {
expect(e.subexpr).toBe('foo[0]')
expect(e.line).toBe(2)
expect(e.column).toBe(9)
// Getting different results from different environments
// bun: TypeError: undefined is not an object (evaluating '_.foo[0]')
if (process.isBun) {
expect(e.subexpr).toBe('foo[0]')
expect(e.line).toBe(2)
expect(e.column).toBe(9)
} else {
// node: TypeError: Cannot read properties of undefined (reading '0')
expect(e.subexpr).toBe('0')
expect(e.line).toBe(2)
expect(e.column).toBe(13)
}
}
})

1 change: 1 addition & 0 deletions packages/nuekit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"dependencies": {
"diff-dom": "^5.0.6",
"es-main": "^1.3.0",
"js-yaml": "^4.1.0",
"nuejs-core": "^0.3.0",
"nuemark": "^0.1.0"
Expand Down
4 changes: 3 additions & 1 deletion packages/nuekit/src/browser/app-router.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

import { onclick, loadPage, setSelected } from './page-router.js'

const is_browser = typeof window == 'object'

const fns = []

async function fire(path) {
Expand All @@ -12,7 +14,7 @@ async function fire(path) {
}

// clear existing routes
addEventListener('before:route', () => {
is_browser && addEventListener('before:route', () => {
fns.splice(0, fns.length)
})

Expand Down
2 changes: 1 addition & 1 deletion packages/nuekit/src/browser/page-router.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function loadPage(path) {


// back button
addEventListener('popstate', e => {
is_browser && addEventListener('popstate', e => {
const { path, is_spa } = e.state || {}
if (path) loadPage(path)
})
Expand Down
2 changes: 1 addition & 1 deletion packages/nuekit/src/builder.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

/* Builders for CSS, JS, and TS */

import { join, extname } from 'node:path'
import { join } from 'node:path'

export async function getBuilder(is_esbuild) {
try {
Expand Down
13 changes: 5 additions & 8 deletions packages/nuekit/src/cli.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env bun

import { log, colors } from './util.js'
import esMain from 'es-main'

// [-npe] --> [-n, -p, -e]
export function expandArgs(args) {
Expand Down Expand Up @@ -103,6 +104,9 @@ async function runCommand(args) {
else if (cmd == 'stats') await nue.stats()
}

// Only run main when called as real CLI
if (esMain(import.meta)) {

const args = getArgs(process.argv)

// help
Expand All @@ -126,11 +130,4 @@ if (args.help) {
}
}









}
5 changes: 3 additions & 2 deletions packages/nuekit/src/site.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

import { join, extname, basename, sep, parse as parsePath } from 'node:path'
import { log, getParts, getAppDir, getDirs, colors } from './util.js'
import { log, getParts, getAppDir, getDirs, colors, getPosixPath } from './util.js'
import { parse as parseNue } from 'nuejs-core/index.js'
import { nuemark } from 'nuemark/index.js'
import { promises as fs } from 'node:fs'
Expand Down Expand Up @@ -125,7 +125,8 @@ export async function createSite(args) {

}).forEach(path => {
const ext = extname(path)
arr.push('/' + join(dir, to_ext ? path.replace(ext, '.' + to_ext) : path))
const subpath = to_ext ? path.replace(ext, '.' + to_ext) : path
arr.push('/' + getPosixPath(join(dir, subpath)))
})

} catch (e) {
Expand Down
11 changes: 9 additions & 2 deletions packages/nuekit/src/util.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

/* misc stuff. think shame.css */
import { sep, parse } from 'node:path'
import { sep, parse, normalize } from 'node:path'


export function log(msg, extra='') {
Expand Down Expand Up @@ -29,6 +29,7 @@ export const colors = getColorFunctions()
/* path parts */

export function getParts(path) {
path = normalize(path)
const { dir, name, base } = parse(path)
const appdir = getAppDir(path)
const url = getUrl(dir, name)
Expand All @@ -37,21 +38,27 @@ export function getParts(path) {


export function getAppDir(path) {
path = normalize(path)
const [ appdir ] = path.split(sep)
return appdir == path ? '' : appdir
}

// getDirs('a/b/c') --> ['a', 'a/b', 'a/b/c']
export function getDirs(dir) {
if (!dir) return []
dir = normalize(dir)
const els = dir.split(sep)
return els.map((el, i) => els.slice(0, i + 1).join(sep))
}

export function getUrl(dir, name) {
let url = dir.replace('\\', '/') + '/'
let url = getPosixPath(dir) + '/'
if (url[0] != '/') url = '/' + url
// if (name != 'index')
url += name + '.html'
return url
}

export function getPosixPath(path) {
return path.replaceAll('\\', '/')
}
19 changes: 19 additions & 0 deletions packages/nuekit/test/kit-init.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { promises as fs } from 'node:fs'
import { join } from 'node:path'
import { init } from '../src/init.js'

// temporary directory
const root = '_test'

// setup and teardown
beforeAll(async () => {
await fs.rm(root, { recursive: true, force: true })
await fs.mkdir(root, { recursive: true })
})
afterAll(async () => await fs.rm(root, { recursive: true, force: true }))

test('init dist/@nue dir', async () => {
await init({ dist: root, is_dev: true, esbuild: false })
const names = await fs.readdir(join(root, '@nue'))
expect(names.length).toBeGreaterThan(7)
})
26 changes: 26 additions & 0 deletions packages/nuekit/test/match-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { getPosixPath } from '../src/util.js'

// https://stackoverflow.com/questions/67325342/how-to-run-os-agnostic-jest-test-files-that-check-paths
// https://jestjs.io/docs/expect#expectextendmatchers
export function toMatchPath(actual, expected) {
const { printReceived, printExpected, matcherHint } = this.utils

const pass = getPosixPath(actual) == expected

return {
pass,
message: () => pass
? matcherHint('.not.toMatchPath') +
'\n\n' +
'Expected path not to match:\n' +
` ${printExpected(expected)}\n` +
'Received:\n' +
` ${printReceived(actual)}`
: matcherHint('.toMatchPath') +
'\n\n' +
'Expected path to match:\n' +
` ${printExpected(expected)}\n` +
'Received:\n' +
` ${printReceived(actual)}`
}
}
8 changes: 6 additions & 2 deletions packages/nuekit/test/misc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { match } from '../src/browser/app-router.js'
import { renderHead } from '../src/layout.js'
import { getArgs } from '../src/cli.js'

import { toMatchPath } from './match-path.js'

expect.extend({ toMatchPath })

const lcss = await findModule('lightningcss')
const stylus = await findModule('stylus')

Expand Down Expand Up @@ -85,8 +89,8 @@ test('app router', async () => {
test('path parts', () => {
const parts = getParts('docs/glossary/semantic-css.md')
expect(parts.url).toBe('/docs/glossary/semantic-css.html')
expect(parts.dir).toBe('docs/glossary')
expect(parts.appdir).toBe('docs')
expect(parts.dir).toMatchPath('docs/glossary')
expect(parts.appdir).toMatchPath('docs')
expect(parts.slug).toBe('semantic-css.html')
})

24 changes: 11 additions & 13 deletions packages/nuekit/test/nuekit.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ import { createSite } from '../src/site.js'
import { createKit } from '../src/nuekit.js'
import { promises as fs } from 'node:fs'
import { join, parse } from 'node:path'
import { init } from '../src/init.js'

import { toMatchPath } from './match-path.js'

expect.extend({ toMatchPath })

// temporary directory
const root = '_test'

// setup and teardown
beforeAll(async () => await fs.mkdir(root, { recursive: true }))
beforeAll(async () => {
await fs.rm(root, { recursive: true, force: true })
await fs.mkdir(root, { recursive: true })
})
afterAll(async () => await fs.rm(root, { recursive: true, force: true }))

// helper function for creating files to the root directory
Expand Down Expand Up @@ -124,7 +130,7 @@ test('content collection', async () => {
expect(coll[0].url).toBe('/blog/first.html')
expect(coll[0].title).toBe('First')
expect(coll[1].title).toBe('Second')
expect(coll[1].dir).toBe('blog/nested')
expect(coll[1].dir).toMatchPath('blog/nested')
expect(coll[1].slug).toBe('hey.html')
})

Expand Down Expand Up @@ -174,20 +180,12 @@ test('getRequestPaths', async () => {
// SPA root
const path = 'admin/index.html'
await write(path)
expect(await site.getRequestPaths('/admin/')).toMatchObject({ path })
expect(await site.getRequestPaths('/admin/customers')).toMatchObject({ path })
expect((await site.getRequestPaths('/admin/')).path).toMatchPath(path)
expect((await site.getRequestPaths('/admin/customers')).path).toMatchPath(path)
expect(await site.getRequestPaths('/admin/readme.html')).toMatchObject({ path: '404.html' })
})



test('init dist/@nue dir', async () => {
await init({ dist: root, is_dev: true, esbuild: false })
const names = await fs.readdir(join(root, '@nue'))
expect(names.length).toBeGreaterThan(7)
})


test('inline CSS', async () => {
const kit = await getKit()
await write('inline/style.css', 'body { margin: 0 }')
Expand Down
13 changes: 10 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2ce6b77

Please sign in to comment.