Skip to content
Draft
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
115 changes: 115 additions & 0 deletions src/test/analyze/attw.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {describe, it, expect, beforeEach, afterEach} from 'vitest';
import {runAttw} from '../../analyze/attw.js';
import {TarballFileSystem} from '../../tarball-file-system.js';
import {LocalFileSystem} from '../../local-file-system.js';
import {createTempDir, cleanupTempDir, createTestPackage} from '../utils.js';
import {pack as packAsTarball} from '@publint/pack';
import fs from 'node:fs/promises';
import path from 'node:path';

describe('runAttw', () => {
let tempDir: string;

beforeEach(async () => {
tempDir = await createTempDir();
});

afterEach(async () => {
await cleanupTempDir(tempDir);
});

async function createTarballFromPackage(
packageData: any,
files: Record<string, string> = {}
): Promise<ArrayBuffer> {
await createTestPackage(tempDir, packageData);

for (const [fileName, content] of Object.entries(files)) {
const filePath = path.join(tempDir, fileName);
const dirPath = path.dirname(filePath);

await fs.mkdir(dirPath, {recursive: true});
await fs.writeFile(filePath, content);
}

const tarballPath = await packAsTarball(tempDir, {
packageManager: 'npm',
ignoreScripts: true,
destination: tempDir
});

const buffer = await fs.readFile(tarballPath);
return buffer.buffer.slice(
buffer.byteOffset,
buffer.byteOffset + buffer.byteLength
) as ArrayBuffer;
}

it('should return empty result for non-TarballFileSystem', async () => {
const localFileSystem = new LocalFileSystem(tempDir);
const result = await runAttw(localFileSystem);

expect(result).toEqual({
messages: []
});
});

it('should suggest when no type definitions found', async () => {
const tarball = await createTarballFromPackage(
{
name: 'test-package',
version: '1.0.0',
type: 'module',
exports: {
'.': './index.js'
}
},
{
'index.js': 'export const test = "hello";'
}
);

const fileSystem = new TarballFileSystem(tarball);
const result = await runAttw(fileSystem);

expect(result.messages).toHaveLength(1);
expect(result.messages[0]).toEqual({
severity: 'suggestion',
score: 0,
message: 'No type definitions found.'
});
});

it('should detect TypeScript issues in package with types', async () => {
const tarball = await createTarballFromPackage(
{
name: 'test-package',
version: '1.0.0',
type: 'module',
types: './index.d.ts',
exports: {
'.': {
types: './index.d.ts',
import: './index.js'
}
}
},
{
'index.js': 'export const test = "hello";',
'index.d.ts': 'export declare const different: string;'
}
);

const fileSystem = new TarballFileSystem(tarball);
const result = await runAttw(fileSystem);

expect(result.messages.length).toBeGreaterThanOrEqual(0);

for (const message of result.messages) {
expect(['error', 'warning', 'suggestion']).toContain(message.severity);
expect(message.score).toBe(0);
expect(typeof message.message).toBe('string');
expect(message.message.length).toBeGreaterThan(0);
}
});
});
124 changes: 124 additions & 0 deletions src/test/analyze/publint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {describe, it, expect, beforeEach, afterEach} from 'vitest';
import {runPublint} from '../../analyze/publint.js';
import {TarballFileSystem} from '../../tarball-file-system.js';
import {LocalFileSystem} from '../../local-file-system.js';
import {createTempDir, cleanupTempDir, createTestPackage} from '../utils.js';
import {pack as packAsTarball} from '@publint/pack';
import fs from 'node:fs/promises';
import path from 'node:path';

describe('runPublint', () => {
let tempDir: string;

beforeEach(async () => {
tempDir = await createTempDir();
});

afterEach(async () => {
await cleanupTempDir(tempDir);
});

async function createTarballFromPackage(
packageData: any,
files: Record<string, string> = {}
): Promise<ArrayBuffer> {
await createTestPackage(tempDir, packageData);

for (const [fileName, content] of Object.entries(files)) {
await fs.writeFile(path.join(tempDir, fileName), content);
}

const tarballPath = await packAsTarball(tempDir, {
packageManager: 'npm',
ignoreScripts: true,
destination: tempDir
});

const buffer = await fs.readFile(tarballPath);
return buffer.buffer.slice(
buffer.byteOffset,
buffer.byteOffset + buffer.byteLength
) as ArrayBuffer;
}

it('should return empty result for non-TarballFileSystem', async () => {
const localFileSystem = new LocalFileSystem(tempDir);
const result = await runPublint(localFileSystem);

expect(result).toEqual({
messages: []
});
});

it('should process package with publint errors', async () => {
const tarball = await createTarballFromPackage(
{
name: 'test-package',
version: '1.0.0',
type: 'module',
main: './non-existent-file.js'
},
{
'index.js': 'export const test = "hello";'
}
);

const fileSystem = new TarballFileSystem(tarball);
const result = await runPublint(fileSystem);

expect(result.messages.length).toBeGreaterThan(0);

for (const message of result.messages) {
expect(['error', 'warning', 'suggestion']).toContain(message.severity);
expect(message.score).toBe(0);
expect(typeof message.message).toBe('string');
expect(message.message.length).toBeGreaterThan(0);
}
});

it('should handle package with multiple publint issues', async () => {
const tarball = await createTarballFromPackage(
{
name: 'test-package',
version: '1.0.0',
type: 'module',
main: './missing-main.js',
exports: {
'.': './missing-export.js'
},
module: './missing-module.js'
},
{
'index.js': 'export const test = "hello";'
}
);

const fileSystem = new TarballFileSystem(tarball);
const result = await runPublint(fileSystem);

expect(result.messages.length).toBeGreaterThan(0);
expect(result.messages.some((m) => m.severity === 'error')).toBe(true);
});

it('should handle package without issues', async () => {
const tarball = await createTarballFromPackage(
{
name: 'test-package',
version: '1.0.0',
type: 'module',
exports: {
'.': './index.js'
}
},
{
'index.js': 'export const test = "hello";'
}
);

const fileSystem = new TarballFileSystem(tarball);
const result = await runPublint(fileSystem);

expect(result).toHaveProperty('messages');
expect(Array.isArray(result.messages)).toBe(true);
});
});
58 changes: 58 additions & 0 deletions test/__snapshots__/help-message.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`--help command > prints the analyze command help 1`] = `
"e18e (cli <version>)

Analyze the project for any warnings or errors

USAGE:
cli analyze <OPTIONS>

OPTIONS:
--pack [pack] Package manager to use for packing (default: auto, choices: auto | npm | yarn | pnpm | bun | none)
--log-level [log-level] Set the log level (debug | info | warn | error) (default: info, choices: debug | info | warn | error)
-h, --help Display this help message
-v, --version Display this version

"
`;

exports[`--help command > prints the migrate command help 1`] = `
"e18e (cli <version>)

Migrate from a package to a more performant alternative.

USAGE:
cli migrate <OPTIONS>

OPTIONS:
--dry-run Don't apply any fixes, only show what would change. (default: false)
--interactive Run in interactive mode. (default: false)
--include [include] Files to migrate (default: **/*.{ts,js})
-h, --help Display this help message
-v, --version Display this version

"
`;

exports[`--help command > prints the up to date help command 1`] = `
"e18e (cli <version>)

USAGE:
cli [(anonymous)] <OPTIONS>
cli <COMMANDS>

COMMANDS:
analyze Analyze the project for any warnings or errors
migrate Migrate from a package to a more performant alternative.

For more info, run any command with the \`--help\` flag:
cli analyze --help
cli migrate --help

OPTIONS:
-h, --help Display this help message
-v, --version Display this version

"
`;
38 changes: 38 additions & 0 deletions test/fixtures/monorepo-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# Dependencies
node_modules
.pnp
.pnp.js

# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# Testing
coverage

# Turbo
.turbo

# Vercel
.vercel

# Build Outputs
.next/
out/
build
dist


# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Misc
.DS_Store
*.pem
Empty file.
Loading