Back to Repositories

Validating EntryResolver Path Resolution in Parcel Bundler

This test suite evaluates the EntryResolver functionality in Parcel bundler, focusing on package.json entry point validation and resolution. The tests verify proper handling of invalid file paths, missing sources, and glob-like entries to ensure robust entry point processing.

Test Coverage Overview

The test suite provides comprehensive coverage of EntryResolver error handling and validation scenarios.

  • Tests invalid source paths in package.json
  • Verifies handling of missing source files
  • Validates non-file source handling
  • Tests target source validation
  • Checks glob-like entry resolution

Implementation Analysis

The testing approach uses async/await patterns with assertion rejection checks to validate error conditions. The implementation leverages Node’s assert.rejects functionality and custom diagnostic messaging for detailed error reporting.

Key testing patterns include:
  • Timeout configurations for async operations
  • Structured diagnostic object validation
  • Path resolution testing
  • Error message format verification

Technical Details

Testing tools and configuration:

  • Flow strict-local type checking
  • Minitest framework
  • Custom DEFAULT_OPTIONS configuration
  • @parcel/diagnostic for error handling
  • @parcel/test-utils for filesystem operations
  • Path resolution utilities

Best Practices Demonstrated

The test suite exemplifies strong testing practices through structured test organization and thorough error condition validation. Notable practices include:

  • Isolated test fixtures
  • Comprehensive error message validation
  • Timeout handling for async operations
  • Structured diagnostic objects
  • Clear test case separation

parcel-bundler/parcel

packages/core/core/test/EntryRequest.test.js

            
// @flow strict-local
import assert from 'assert';
import path from 'path';
import {md} from '@parcel/diagnostic';
import {inputFS as fs} from '@parcel/test-utils';
import {EntryResolver} from '../src/requests/EntryRequest';
import {DEFAULT_OPTIONS as _DEFAULT_OPTIONS} from './test-utils';

const DEFAULT_OPTIONS = {
  ..._DEFAULT_OPTIONS,
  defaultTargetOptions: {
    ..._DEFAULT_OPTIONS.defaultTargetOptions,
    sourceMaps: true,
  },
};

const INVALID_SOURCE_MISSING_FIXTURE_PATH = path.join(
  __dirname,
  'fixtures/invalid-source-missing',
);

const INVALID_SOURCE_NOT_FILE_FIXTURE_PATH = path.join(
  __dirname,
  'fixtures/invalid-source-not-file',
);

const INVALID_TARGET_SOURCE_MISSING_FIXTURE_PATH = path.join(
  __dirname,
  'fixtures/invalid-target-source-missing',
);

const INVALID_TARGET_SOURCE_NOT_FILE_FIXTURE_PATH = path.join(
  __dirname,
  'fixtures/invalid-target-source-not-file',
);

const GLOB_LIKE_FIXTURE_PATH = path.join(
  __dirname,
  'fixtures/glob-like/[entry].js',
);

describe('EntryResolver', function () {
  let entryResolver = new EntryResolver({...DEFAULT_OPTIONS});

  it('rejects missing source in package.json', async function () {
    this.timeout(10000);
    // $FlowFixMe assert.rejects is Node 10+
    await assert.rejects(
      () => entryResolver.resolveEntry(INVALID_SOURCE_MISSING_FIXTURE_PATH),
      {
        diagnostics: [
          {
            origin: '@parcel/core',
            message: md`${path.join(
              path.relative(fs.cwd(), INVALID_SOURCE_MISSING_FIXTURE_PATH),
              'missing.js',
            )} does not exist.`,
            codeFrames: [
              {
                filePath: path.join(
                  INVALID_SOURCE_MISSING_FIXTURE_PATH,
                  'package.json',
                ),
                codeHighlights: [
                  {
                    message: undefined,
                    start: {
                      line: 4,
                      column: 13,
                    },
                    end: {
                      line: 4,
                      column: 24,
                    },
                  },
                ],
              },
            ],
            hints: [],
          },
        ],
      },
    );
  });
  it('rejects non-file source in package.json', async function () {
    this.timeout(10000);
    // $FlowFixMe assert.rejects is Node 10+
    await assert.rejects(
      () => entryResolver.resolveEntry(INVALID_SOURCE_NOT_FILE_FIXTURE_PATH),
      {
        diagnostics: [
          {
            origin: '@parcel/core',
            message: md`${path.join(
              path.relative(fs.cwd(), INVALID_SOURCE_NOT_FILE_FIXTURE_PATH),
              'src',
            )} is not a file.`,
            codeFrames: [
              {
                filePath: path.join(
                  INVALID_SOURCE_NOT_FILE_FIXTURE_PATH,
                  'package.json',
                ),
                codeHighlights: [
                  {
                    message: undefined,
                    start: {
                      line: 4,
                      column: 13,
                    },
                    end: {
                      line: 4,
                      column: 17,
                    },
                  },
                ],
              },
            ],
          },
        ],
      },
    );
  });
  it('rejects missing target source in package.json', async function () {
    this.timeout(10000);
    // $FlowFixMe assert.rejects is Node 10+
    await assert.rejects(
      () =>
        entryResolver.resolveEntry(INVALID_TARGET_SOURCE_MISSING_FIXTURE_PATH),
      {
        diagnostics: [
          {
            origin: '@parcel/core',
            message: md`${path.join(
              path.relative(
                fs.cwd(),
                INVALID_TARGET_SOURCE_MISSING_FIXTURE_PATH,
              ),
              'missing.js',
            )} does not exist.`,
            codeFrames: [
              {
                filePath: path.join(
                  INVALID_TARGET_SOURCE_MISSING_FIXTURE_PATH,
                  'package.json',
                ),
                codeHighlights: [
                  {
                    message: undefined,
                    start: {
                      line: 6,
                      column: 17,
                    },
                    end: {
                      line: 6,
                      column: 28,
                    },
                  },
                ],
              },
            ],
            hints: [],
          },
        ],
      },
    );
  });
  it('rejects non-file target source in package.json', async function () {
    this.timeout(10000);
    // $FlowFixMe assert.rejects is Node 10+
    await assert.rejects(
      () =>
        entryResolver.resolveEntry(INVALID_TARGET_SOURCE_NOT_FILE_FIXTURE_PATH),
      {
        diagnostics: [
          {
            origin: '@parcel/core',
            message: md`${path.join(
              path.relative(
                fs.cwd(),
                INVALID_TARGET_SOURCE_NOT_FILE_FIXTURE_PATH,
              ),
              'src',
            )} is not a file.`,
            codeFrames: [
              {
                filePath: path.join(
                  INVALID_TARGET_SOURCE_NOT_FILE_FIXTURE_PATH,
                  'package.json',
                ),
                codeHighlights: [
                  {
                    message: undefined,
                    start: {
                      line: 6,
                      column: 17,
                    },
                    end: {
                      line: 6,
                      column: 21,
                    },
                  },
                ],
              },
            ],
          },
        ],
      },
    );
  });
  it('does not time out on glob-like entry', async function () {
    this.timeout(10000);
    await entryResolver.resolveEntry(GLOB_LIKE_FIXTURE_PATH);
  });
});