Skip to content

Commit

Permalink
Merge pull request #1811 from BlueCutOfficial/virtual-test-support-st…
Browse files Browse the repository at this point in the history
…yles

Module Resolver: Virtual test-support.css
  • Loading branch information
mansona committed Apr 10, 2024
2 parents cb8efec + 2b91aa0 commit ea2a455
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 20 deletions.
20 changes: 1 addition & 19 deletions packages/compat/src/compat-app-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,7 @@ export class CompatAppBuilder {
// virtual test-support.js
html.insertScriptTag(html.implicitTestScripts, '@embroider/core/test-support.js');

let implicitTestStylesAsset = this.implicitTestStylesAsset(prepared, parentEngine);
if (implicitTestStylesAsset) {
html.insertStyleLink(html.implicitTestStyles, implicitTestStylesAsset.relativePath);
}
html.insertStyleLink(html.implicitTestStyles, '@embroider/core/test-support.css');
}

private implicitScriptsAsset(
Expand All @@ -553,21 +550,6 @@ export class CompatAppBuilder {
return asset;
}

private implicitTestStylesAsset(
prepared: Map<string, InternalAsset>,
application: AppFiles
): InternalAsset | undefined {
let asset = prepared.get('assets/test-support.css');
if (!asset) {
let implicitTestStyles = this.impliedAssets('implicit-test-styles', application);
if (implicitTestStyles.length > 0) {
asset = new ConcatenatedAsset('assets/test-support.css', implicitTestStyles, this.resolvableExtensionsPattern);
prepared.set(asset.relativePath, asset);
}
}
return asset;
}

// recurse to find all active addons that don't cross an engine boundary.
// Inner engines themselves will be returned, but not those engines' children.
// The output set's insertion order is the proper ember-cli compatible
Expand Down
27 changes: 27 additions & 0 deletions packages/core/src/module-resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export class Resolver {
request = this.handleImplicitModules(request);
request = this.handleImplicitTestScripts(request);
request = this.handleVendorStyles(request);
request = this.handleTestSupportStyles(request);
request = this.handleRenaming(request);
// we expect the specifier to be app relative at this point - must be after handleRenaming
request = this.generateFastbootSwitch(request);
Expand Down Expand Up @@ -445,6 +446,32 @@ export class Resolver {
return logTransition('test-support', request, request.virtualize(resolve(pkg.root, '-embroider-test-support.js')));
}

private handleTestSupportStyles<R extends ModuleRequest>(request: R): R {
//TODO move the extra forwardslash handling out into the vite plugin
const candidates = [
'@embroider/core/test-support.css',
'/@embroider/core/test-support.css',
'./@embroider/core/test-support.css',
];

if (!candidates.includes(request.specifier)) {
return request;
}

let pkg = this.packageCache.ownerOfFile(request.fromFile);
if (pkg?.root !== this.options.engines[0].root) {
throw new Error(
`bug: found an import of ${request.specifier} in ${request.fromFile}, but this is not the top-level Ember app. The top-level Ember app is the only one that has support for @embroider/core/test-support.css. If you think something should be fixed in Embroider, please open an issue on https://github.com/embroider-build/embroider/issues.`
);
}

return logTransition(
'test-support-styles',
request,
request.virtualize(resolve(pkg.root, '-embroider-test-support-styles.css'))
);
}

private async handleGlobalsCompat<R extends ModuleRequest>(request: R): Promise<R> {
if (isTerminal(request)) {
return request;
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/virtual-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Resolver, AddonPackage, Package } from '.';
import { explicitRelative, extensionsPattern } from '.';
import { compile } from './js-handlebars';
import { decodeImplicitTestScripts, renderImplicitTestScripts } from './virtual-test-support';

import { decodeTestSupportStyles, renderTestSupportStyles } from './virtual-test-support-styles';
import { decodeVirtualVendorStyles, renderVendorStyles } from './virtual-vendor-styles';

const externalESPrefix = '/@embroider/ext-es/';
Expand Down Expand Up @@ -53,6 +53,11 @@ export function virtualContent(filename: string, resolver: Resolver): VirtualCon
return renderVendorStyles(filename, resolver);
}

let isTestSupportStyles = decodeTestSupportStyles(filename);
if (isTestSupportStyles) {
return renderTestSupportStyles(filename, resolver);
}

throw new Error(`not an @embroider/core virtual file: ${filename}`);
}

Expand Down
70 changes: 70 additions & 0 deletions packages/core/src/virtual-test-support-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type { Package } from '@embroider/shared-internals';
import type { V2AddonPackage } from '@embroider/shared-internals/src/package';
import { readFileSync } from 'fs';
import { sortBy } from 'lodash';
import resolve from 'resolve';
import type { Engine } from './app-files';
import type { Resolver } from './module-resolver';
import type { VirtualContentResult } from './virtual-content';

export function decodeTestSupportStyles(filename: string): boolean {
return filename.endsWith('-embroider-test-support-styles.css');
}

export function renderTestSupportStyles(filename: string, resolver: Resolver): VirtualContentResult {
const owner = resolver.packageCache.ownerOfFile(filename);
if (!owner) {
throw new Error(`Failed to find a valid owner for ${filename}`);
}
return { src: getTestSupportStyles(owner, resolver), watches: [] };
}

function getTestSupportStyles(owner: Package, resolver: Resolver): string {
let engineConfig = resolver.owningEngine(owner);
let engine: Engine = {
package: owner,
addons: new Map(
engineConfig.activeAddons.map(addon => [
resolver.packageCache.get(addon.root) as V2AddonPackage,
addon.canResolveFromFile,
])
),
isApp: true,
modulePrefix: resolver.options.modulePrefix,
appRelativePath: 'NOT_USED_DELETE_ME',
};

return generateTestSupportStyles(engine);
}

function generateTestSupportStyles(engine: Engine): string {
let result: string[] = impliedAddonTestSupportStyles(engine).map((sourcePath: string): string => {
let source = readFileSync(sourcePath);
return `${source}`;
});

return result.join('') as string;
}

function impliedAddonTestSupportStyles(engine: Engine): string[] {
let result: Array<string> = [];
for (let addon of sortBy(Array.from(engine.addons.keys()), pkg => {
switch (pkg.name) {
case 'loader.js':
return 0;
case 'ember-source':
return 10;
default:
return 1000;
}
})) {
let implicitStyles = addon.meta['implicit-test-styles'];
if (implicitStyles) {
let options = { basedir: addon.root };
for (let mod of implicitStyles) {
result.push(resolve.sync(mod, options));
}
}
}
return result;
}

0 comments on commit ea2a455

Please sign in to comment.