+
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
146 changes: 92 additions & 54 deletions packages/vite-plugin-angular/src/lib/component-resolvers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,68 @@ import { StyleUrlsResolver, TemplateUrlsResolver } from './component-resolvers';
import { normalizePath } from 'vite';
import { relative } from 'node:path';

const WINDOWS_DRIVE_IN_PATH_RE = /\|[A-Z]:/i;

// array version of normalizePath
const normalizePaths = (paths: string[]) =>
paths.map((path) => normalizePath(path));

// OS agnostic paths array comparison
// Two normalized paths are the same if path.relative(p1, p2) === ''
// In Windows a normalized absolute path includes the drive i.e. C:
const thePathsAreEqual = (actual: string[], expected: string[]) => {
const arr1 = normalizePaths(actual);
const arr2 = normalizePaths(expected);

// check arrays match in length
if (arr1.length !== arr2.length) {
return false;
}

// check each path of the two arrays are the same
for (let i = 0; i < arr1.length; i++) {
if (relative(arr1[i], arr2[i]) !== '') {
return false;
paths.map((path) =>
normalizePath(path).replace(WINDOWS_DRIVE_IN_PATH_RE, '|'),
);

interface CustomMatchers<R = unknown> {
toMatchNormalizedPaths: (expected: string[]) => R;
}

declare module 'vitest' {
interface Assertion<T = any> extends CustomMatchers<T> {}
interface AsymmetricMatchersContaining extends CustomMatchers {}
}

expect.extend({
// OS agnostic paths array comparison
// Two normalized paths are the same if path.relative(p1, p2) === ''
// In Windows a normalized absolute path includes the drive i.e. C:
toMatchNormalizedPaths(actual: unknown, expected: string[]) {
const { matcherHint, printExpected, printReceived, diff } = this.utils;

if (!(Array.isArray(actual) && actual.length === expected.length)) {
return {
pass: false,
message: () =>
matcherHint('toMatchNormalizedPaths') +
'\n\n' +
'Expected:\n' +
` type: ${printExpected('Array')}\n` +
` length: ${printExpected(expected.length)}\n` +
'Received:\n' +
` type: ${printReceived(Array.isArray(actual) ? 'Array' : typeof actual)}\n` +
` length: ${printReceived(Array.isArray(actual) ? actual.length : '-')}`,
};
}

const normalizedActual = normalizePaths(actual);
const normalizedExpected = normalizePaths(expected);

const areSame = normalizedExpected.every(
(path, index) => relative(normalizedActual[index], path) === '',
);
if (!areSame) {
return {
pass: false,
message: () =>
matcherHint('toMatchNormalizedPaths') +
'\n\n' +
'(normalized values)\n' +
diff(normalizedExpected, normalizedActual),
};
}
}

return true;
};
return {
pass: true,
message: () => 'Paths match',
};
},
});

describe('component-resolvers', () => {
const id = '/path/to/src/app.component.ts';
Expand All @@ -42,13 +79,13 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
];
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle single line styleUrl', () => {
Expand All @@ -59,13 +96,13 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
];
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle multi-line styleUrls', () => {
Expand All @@ -79,15 +116,15 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
'../styles.css|/path/to/styles.css',
];

const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle wrapped multi-line styleUrls', () => {
Expand All @@ -101,7 +138,7 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
'./another.css|/path/to/src/another.css',
'../styles.css|/path/to/styles.css',
Expand All @@ -110,7 +147,7 @@ describe('component-resolvers', () => {
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle styleUrls with route params in filename', () => {
Expand All @@ -121,13 +158,13 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./[param].component.css|/path/to/src/[param].component.css',
];
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle styleUrl with backticks', () => {
Expand All @@ -138,13 +175,13 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
];
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle multi-line styleUrls with backticks', () => {
Expand All @@ -158,15 +195,15 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
'../styles.css|/path/to/styles.css',
];

const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle multi-line styleUrls with backticks and single quotes', () => {
Expand All @@ -180,15 +217,15 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
'../styles.css|/path/to/styles.css',
];

const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});

it('should handle wrapped multi-line styleUrls with backticks', () => {
Expand All @@ -202,7 +239,7 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualPaths = [
const expectedPaths = [
'./app.component.css|/path/to/src/app.component.css',
'./another.css|/path/to/src/another.css',
'../styles.css|/path/to/styles.css',
Expand All @@ -211,7 +248,7 @@ describe('component-resolvers', () => {
const styleUrlsResolver = new StyleUrlsResolver();
const resolvedPaths = styleUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedPaths, actualPaths)).toBe(true);
expect(resolvedPaths).toMatchNormalizedPaths(expectedPaths);
});
});

Expand All @@ -227,12 +264,12 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualUrl =
const expectedUrl =
'./app.component.html|/path/to/src/app.component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([expectedUrl]);
});

it('should handle templateUrls with single quotes and route params', () => {
Expand All @@ -243,12 +280,12 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualUrl =
const expectedUrl =
'./[param].component.html|/path/to/src/[param].component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([expectedUrl]);
});

it('should handle templateUrls with double quotes', () => {
Expand All @@ -259,12 +296,12 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualUrl =
const expectedUrl =
'./app.component.html|/path/to/src/app.component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([expectedUrl]);
});

it('should handle templateUrls with double quotes and route params', () => {
Expand All @@ -275,12 +312,12 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualUrl =
const expectedUrl =
'./[param].component.html|/path/to/src/[param].component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([expectedUrl]);
});

it('should handle multiple templateUrls in a single file', () => {
Expand All @@ -296,16 +333,17 @@ describe('component-resolvers', () => {
export class MyComponentTwo {}
`;

const actualUrl1 =
const expectedUrl1 =
'./app.component.html|/path/to/src/app.component.html';
const actualUrl2 =
const expectedUrl2 =
'./app1.component.html|/path/to/src/app1.component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(
thePathsAreEqual(resolvedTemplateUrls, [actualUrl1, actualUrl2]),
).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([
expectedUrl1,
expectedUrl2,
]);
});

it('should ignore commented out templateUrls', () => {
Expand All @@ -330,12 +368,12 @@ describe('component-resolvers', () => {
export class MyComponent {}
`;

const actualUrl =
const expectedUrl =
'./app.component.html|/path/to/src/app.component.html';
const templateUrlsResolver = new TemplateUrlsResolver();
const resolvedTemplateUrls = templateUrlsResolver.resolve(code, id);

expect(thePathsAreEqual(resolvedTemplateUrls, [actualUrl])).toBe(true);
expect(resolvedTemplateUrls).toMatchNormalizedPaths([expectedUrl]);
});
});
});
Expand Down
5 changes: 1 addition & 4 deletions packages/vite-plugin-angular/src/lib/component-resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,7 @@ export class TemplateUrlsResolver {
}

const templateUrlPaths = getTemplateUrls(code).map(
(url) =>
`${url}|${normalizePath(
resolve(dirname(id), url).replace(/\\/g, '/'),
)}`,
(url) => `${url}|${normalizePath(resolve(dirname(id), url))}`,
);

this.templateUrlsCache.set(id, { code, templateUrlPaths });
Expand Down
Loading
点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载