Skip to content
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
26 changes: 3 additions & 23 deletions .github/workflows/_local-not-for-reuse-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,14 @@ jobs:
test-npm-packages:
name: Test NPM Packages
runs-on: ubuntu-latest
timeout-minutes: 60
timeout-minutes: 15
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
autocrlf: false
persist-credentials: false

- uses: SocketDev/socket-registry/.github/actions/setup-and-install@bab1dc8adc59a21c04fa73d3dd4a333c12e2ca9b # main
with:
node-version: 22
socket-api-key: ${{ secrets.SOCKET_API_KEY }}

- uses: SocketDev/socket-registry/.github/actions/cache-npm-packages@bab1dc8adc59a21c04fa73d3dd4a333c12e2ca9b # main

- name: Verify sfw is installed
shell: bash
run: |
if [ -z "$SFW_BIN" ] || [ ! -x "$SFW_BIN" ]; then
echo "Error: sfw is not installed — run SocketDev/socket-registry/.github/actions/setup first" >&2
exit 1
fi

- name: Build registry
- name: Build and test npm packages
shell: bash
run: |
pnpm run build

- name: Run npm package tests
shell: bash
run: |
node scripts/npm/test-npm-packages.mjs
pnpm run test:npm
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"publish:ci": "node scripts/publish.mjs --skip-build --tag ${DIST_TAG:-latest}",
"release-npm": "node scripts/npm/release-npm-packages.mjs",
"test": "node scripts/test.mjs",
"test:npm": "node scripts/npm/run-vitest-npm.mjs",
"update": "node scripts/update.mjs",
"validate-ci": "node scripts/testing/reproduce-ci-locally.mjs",
"validate-packages": "node scripts/testing/validate-package-tests.mjs"
Expand Down
15 changes: 15 additions & 0 deletions scripts/npm/run-vitest-npm.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/usr/bin/env node
// Run vitest on test/npm/ packages.
// Sets INCLUDE_NPM_TESTS so vitest config includes test/npm/.
import { spawn } from '@socketsecurity/lib/spawn'

process.env['INCLUDE_NPM_TESTS'] = '1'
const result = await spawn(
'pnpm',
['exec', 'vitest', 'run', 'test/npm/', ...process.argv.slice(2)],
{
shell: process.platform === 'win32',
stdio: 'inherit',
},
)
process.exitCode = result.code ?? 0
6 changes: 3 additions & 3 deletions scripts/npm/test-npm-packages.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ const { values: cliArgs } = parseArgs({
},
'download-concurrency': {
type: 'string',
default: getCI() ? (WIN32 ? '10' : '20') : '50',
default: getCI() ? '3' : '20',
},
'install-concurrency': {
type: 'string',
default: getCI() ? (WIN32 ? '5' : '10') : '30',
default: getCI() ? '3' : '10',
},
'test-concurrency': {
type: 'string',
default: getCI() ? (WIN32 ? '3' : '8') : '40',
default: getCI() ? '3' : '20',
},
force: {
type: 'boolean',
Expand Down
26 changes: 20 additions & 6 deletions scripts/utils/package.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -371,14 +371,24 @@ export async function installPackageForTesting(
),
)

// Write pnpm-workspace.yaml with v11 workarounds.
await fs.writeFile(
path.join(packageTempDir, 'pnpm-workspace.yaml'),
'packages:\n - .\n\nregistrySupportsTimeField: false\n',
)

// Install the package.
const packageSpec = versionSpec.startsWith('https://')
? versionSpec
: `${packageName}@${versionSpec}`

await runCommand('pnpm', ['add', packageSpec, ...PNPM_NPM_LIKE_FLAGS], {
cwd: packageTempDir,
})
await runCommand(
PNPM_REAL_BIN,
['add', packageSpec, ...PNPM_HOISTED_INSTALL_FLAGS],
{
cwd: packageTempDir,
},
)

installedPath = path.join(packageTempDir, 'node_modules', packageName)

Expand Down Expand Up @@ -496,9 +506,13 @@ export async function installPackageForTesting(
await fs.writeFile(pkgJsonPath, JSON.stringify(pkgJson, null, 2))

// Install dependencies with pnpm.
await runCommand('pnpm', ['install', ...PNPM_HOISTED_INSTALL_FLAGS], {
cwd: installedPath,
})
await runCommand(
PNPM_REAL_BIN,
['install', ...PNPM_HOISTED_INSTALL_FLAGS],
{
cwd: installedPath,
},
)

return {
installed: true,
Expand Down
3 changes: 2 additions & 1 deletion test/npm/aggregate-error.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
const aggregateError = new AggregateError(errors)

expect(aggregateError).toBeInstanceOf(Error)
expect(aggregateError.message).toBe('')
expect(aggregateError.message).toContain('error 1')
expect(aggregateError.message).toContain('error 2')
expect(Array.isArray(aggregateError.errors)).toBe(true)
expect(aggregateError.errors.length).toBe(2)
})
Expand Down
14 changes: 13 additions & 1 deletion test/npm/array.of.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,19 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
},
})

const expected = Object.assign(new MyType(), { 0: 'abc', length: 1 })
const expected = new MyType()
Object.defineProperty(expected, '0', {
value: 'abc',
writable: true,
enumerable: true,
configurable: true,
})
Object.defineProperty(expected, 'length', {
value: 1,
writable: true,
enumerable: true,
configurable: true,
})
expect(of.call(MyType, 'abc')).toEqual(expected)
})
})
9 changes: 0 additions & 9 deletions test/npm/array.prototype.every.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
every([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('true thunk callback yields true', () => {
expect(every([], trueThunk)).toBe(true)
Expand Down
9 changes: 0 additions & 9 deletions test/npm/array.prototype.filter.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -170,15 +170,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
filter([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('returns a new empty array', () => {
const arr: any[] = []
Expand Down
9 changes: 0 additions & 9 deletions test/npm/array.prototype.findlast.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
findLast([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('true thunk callback yields undefined', () => {
expect(findLast([], trueThunk)).toBe(undefined)
Expand Down
9 changes: 0 additions & 9 deletions test/npm/array.prototype.findlastindex.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
findLastIndex([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('true thunk callback yields -1', () => {
expect(findLastIndex([], trueThunk)).toBe(-1)
Expand Down
81 changes: 81 additions & 0 deletions test/npm/array.prototype.flatmap.test.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* @fileoverview Tests for array.prototype.flatmap NPM package override.
* Ported 1:1 from upstream v1.3.3 (7ebde137):
* https://github.com/es-shims/Array.prototype.flatMap/blob/7ebde137246788a04036a73f1a6ffed5b600f22e/test/tests.js
*/

import { describe, expect, it } from 'vitest'

import { setupNpmPackageTest } from '../utils/npm-package-helper.mts'

const {
eco,
module: flatMap,
skip,
sockRegPkgName,
} = await setupNpmPackageTest(import.meta.url)

describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
describe('callback function', () => {
it.each([[], {}, true, false, 42, 'foo', /a/g, null])(
'throws for non-function %s',
nonFunction => {
expect(() => flatMap([], nonFunction)).toThrow(TypeError)
},
)
})

describe('flatMaps', () => {
it('flattens and maps to tuples of item/index', () => {
const mapped = flatMap([1, [2], [3, 4]], (x: unknown, i: number) => [
x,
i,
])
const expected = [1, 0, [2], 1, [3, 4], 2]
expect(mapped).toEqual(expected)
expect(mapped.length).toBe(expected.length)
})

it('thisArg works as expected', () => {
const context = {}
let actual: unknown
flatMap(
[1],
function (this: unknown) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
actual = this
},
context,
)
expect(actual).toBe(context)
})
})

describe('sparse arrays', () => {
it('an array hole is treated the same as an empty array', () => {
const identity = (x: unknown) => x
// eslint-disable-next-line no-sparse-arrays
expect(flatMap([, [1]], identity)).toEqual(flatMap([[], [1]], identity))
})
})

describe('test262: staging test from v8', () => {
it('handles array growth during callback', () => {
const arr1 = [0, 1, 2, 3]
const f = (e: number) => {
arr1[4] = 42
return e
}
expect(flatMap(arr1, f)).toEqual([0, 1, 2, 3])
})

it('handles array shrink during callback', () => {
const arr2 = [0, 1, 2, 3]
const g = (e: number) => {
arr2.length = 3
return e
}
expect(flatMap(arr2, g)).toEqual([0, 1, 2])
})
})
})
9 changes: 0 additions & 9 deletions test/npm/array.prototype.foreach.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -126,15 +126,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
forEach([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('returns undefined', () => {
const arr: any[] = []
Expand Down
9 changes: 0 additions & 9 deletions test/npm/array.prototype.map.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,6 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
])
})

it('sets the right context when given none (sloppy mode)', () => {
let context: any
map([1], function (this: any) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
context = this
})
expect(context).toBe(globalThis)
})

describe('empty array', () => {
it('returns a new empty array', () => {
const arr: any[] = []
Expand Down
2 changes: 1 addition & 1 deletion test/npm/array.prototype.reduce.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe(`${eco} > ${sockRegPkgName}`, { skip }, () => {
expect(value).toBe(expectedValue)
expect(key).toBe(0)
expect(list).toBe(arr)
expect(this).toBe(globalThis)
expect(this).toBe(undefined)
return expectedResult
},
initialValue,
Expand Down
Loading