Skip to content

Commit 89665b5

Browse files
iclantonclaude
andcommitted
[heft-sass-plugin] Add unit tests for doNotTrimOriginalFileExtension option
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ff73c70 commit 89665b5

File tree

2 files changed

+169
-2
lines changed

2 files changed

+169
-2
lines changed

heft-plugins/heft-sass-plugin/src/test/SassProcessor.test.ts

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4+
import path from 'node:path';
5+
46
import { FileSystem } from '@rushstack/node-core-library';
57
import { MockScopedLogger } from '@rushstack/heft/lib/pluginFramework/logging/MockScopedLogger';
68
import { StringBufferTerminalProvider, Terminal } from '@rushstack/terminal';
79

810
import { type ICssOutputFolder, type ISassProcessorOptions, SassProcessor } from '../SassProcessor';
911

10-
const projectFolder: string = `${__dirname}/../..`;
11-
const fixturesFolder: string = `${__dirname}/fixtures`;
12+
const projectFolder: string = path.resolve(__dirname, '../..');
13+
const fixturesFolder: string = path.resolve(__dirname, '../../src/test/fixtures');
1214

1315
// Fake output folder paths — never actually written to disk because FileSystem.writeFileAsync is mocked.
1416
const CSS_OUTPUT_FOLDER: string = '/fake/output/css';
@@ -18,6 +20,7 @@ type ICreateProcessorOptions = Partial<
1820
Pick<
1921
ISassProcessorOptions,
2022
| 'cssOutputFolders'
23+
| 'doNotTrimOriginalFileExtension'
2124
| 'dtsOutputFolders'
2225
| 'exportAsDefault'
2326
| 'fileExtensions'
@@ -467,6 +470,54 @@ describe(SassProcessor.name, () => {
467470
});
468471
});
469472

473+
describe('doNotTrimOriginalFileExtension', () => {
474+
it('strips the source extension by default (doNotTrimOriginalFileExtension: false)', async () => {
475+
const { processor } = createProcessor(terminalProvider);
476+
await compileFixtureAsync(processor, 'classes-and-exports.module.scss');
477+
// Default: "classes-and-exports.module.scss" → "classes-and-exports.module.css"
478+
const css: string = writtenFiles.get(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.css`)!;
479+
expect(css).toBeDefined();
480+
expect(writtenFiles.has(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.scss.css`)).toBe(false);
481+
});
482+
483+
it('preserves the source extension when doNotTrimOriginalFileExtension is true', async () => {
484+
const { processor } = createProcessor(terminalProvider, { doNotTrimOriginalFileExtension: true });
485+
await compileFixtureAsync(processor, 'classes-and-exports.module.scss');
486+
// "classes-and-exports.module.scss" → "classes-and-exports.module.scss.css"
487+
const css: string = writtenFiles.get(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.scss.css`)!;
488+
expect(css).toBeDefined();
489+
expect(writtenFiles.has(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.css`)).toBe(false);
490+
});
491+
492+
it('uses the .scss.css filename in JS shims when doNotTrimOriginalFileExtension is true', async () => {
493+
const { processor } = createProcessor(terminalProvider, {
494+
doNotTrimOriginalFileExtension: true,
495+
cssOutputFolders: [{ folder: CSS_OUTPUT_FOLDER, shimModuleFormat: 'commonjs' }]
496+
});
497+
await compileFixtureAsync(processor, 'classes-and-exports.module.scss');
498+
const shim: string = writtenFiles.get(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.scss.js`)!;
499+
expect(shim).toContain(`require("./classes-and-exports.module.scss.css")`);
500+
});
501+
502+
it('the CSS content is the same regardless of doNotTrimOriginalFileExtension', async () => {
503+
const { processor: processorDefault } = createProcessor(terminalProvider);
504+
await compileFixtureAsync(processorDefault, 'classes-and-exports.module.scss');
505+
const cssDefault: string = writtenFiles.get(`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.css`)!;
506+
507+
writtenFiles.clear();
508+
509+
const { processor: processorPreserve } = createProcessor(terminalProvider, {
510+
doNotTrimOriginalFileExtension: true
511+
});
512+
await compileFixtureAsync(processorPreserve, 'classes-and-exports.module.scss');
513+
const cssPreserve: string = writtenFiles.get(
514+
`${CSS_OUTPUT_FOLDER}/classes-and-exports.module.scss.css`
515+
)!;
516+
517+
expect(cssDefault).toEqual(cssPreserve);
518+
});
519+
});
520+
470521
describe('error reporting', () => {
471522
it('emits an error for invalid SCSS syntax', async () => {
472523
const { processor, logger } = createProcessor(terminalProvider);

heft-plugins/heft-sass-plugin/src/test/__snapshots__/SassProcessor.test.ts.snap

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,122 @@ export default styles;",
279279
}
280280
`;
281281

282+
exports[`SassProcessor doNotTrimOriginalFileExtension preserves the source extension when doNotTrimOriginalFileExtension is true: terminal-output 1`] = `
283+
Array [
284+
"[verbose] Checking for changes to 1 files...[n]",
285+
"[ log] Compiling 1 files...[n]",
286+
]
287+
`;
288+
289+
exports[`SassProcessor doNotTrimOriginalFileExtension preserves the source extension when doNotTrimOriginalFileExtension is true: written-files 1`] = `
290+
Map {
291+
"/fake/output/dts/classes-and-exports.module.scss.d.ts" => "declare interface IStyles {
292+
themeColor: string;
293+
spacing: string;
294+
root: string;
295+
highlighted: string;
296+
}
297+
declare const styles: IStyles;
298+
export default styles;",
299+
"/fake/output/css/classes-and-exports.module.scss.css" => ".root {
300+
color: red;
301+
font-size: 14px;
302+
}
303+
304+
.highlighted {
305+
background-color: yellow;
306+
}",
307+
}
308+
`;
309+
310+
exports[`SassProcessor doNotTrimOriginalFileExtension strips the source extension by default (doNotTrimOriginalFileExtension: false): terminal-output 1`] = `
311+
Array [
312+
"[verbose] Checking for changes to 1 files...[n]",
313+
"[ log] Compiling 1 files...[n]",
314+
]
315+
`;
316+
317+
exports[`SassProcessor doNotTrimOriginalFileExtension strips the source extension by default (doNotTrimOriginalFileExtension: false): written-files 1`] = `
318+
Map {
319+
"/fake/output/dts/classes-and-exports.module.scss.d.ts" => "declare interface IStyles {
320+
themeColor: string;
321+
spacing: string;
322+
root: string;
323+
highlighted: string;
324+
}
325+
declare const styles: IStyles;
326+
export default styles;",
327+
"/fake/output/css/classes-and-exports.module.css" => ".root {
328+
color: red;
329+
font-size: 14px;
330+
}
331+
332+
.highlighted {
333+
background-color: yellow;
334+
}",
335+
}
336+
`;
337+
338+
exports[`SassProcessor doNotTrimOriginalFileExtension the CSS content is the same regardless of doNotTrimOriginalFileExtension: terminal-output 1`] = `
339+
Array [
340+
"[verbose] Checking for changes to 1 files...[n]",
341+
"[ log] Compiling 1 files...[n]",
342+
"[verbose] Checking for changes to 1 files...[n]",
343+
"[ log] Compiling 1 files...[n]",
344+
]
345+
`;
346+
347+
exports[`SassProcessor doNotTrimOriginalFileExtension the CSS content is the same regardless of doNotTrimOriginalFileExtension: written-files 1`] = `
348+
Map {
349+
"/fake/output/dts/classes-and-exports.module.scss.d.ts" => "declare interface IStyles {
350+
themeColor: string;
351+
spacing: string;
352+
root: string;
353+
highlighted: string;
354+
}
355+
declare const styles: IStyles;
356+
export default styles;",
357+
"/fake/output/css/classes-and-exports.module.scss.css" => ".root {
358+
color: red;
359+
font-size: 14px;
360+
}
361+
362+
.highlighted {
363+
background-color: yellow;
364+
}",
365+
}
366+
`;
367+
368+
exports[`SassProcessor doNotTrimOriginalFileExtension uses the .scss.css filename in JS shims when doNotTrimOriginalFileExtension is true: terminal-output 1`] = `
369+
Array [
370+
"[verbose] Checking for changes to 1 files...[n]",
371+
"[ log] Compiling 1 files...[n]",
372+
]
373+
`;
374+
375+
exports[`SassProcessor doNotTrimOriginalFileExtension uses the .scss.css filename in JS shims when doNotTrimOriginalFileExtension is true: written-files 1`] = `
376+
Map {
377+
"/fake/output/dts/classes-and-exports.module.scss.d.ts" => "declare interface IStyles {
378+
themeColor: string;
379+
spacing: string;
380+
root: string;
381+
highlighted: string;
382+
}
383+
declare const styles: IStyles;
384+
export default styles;",
385+
"/fake/output/css/classes-and-exports.module.scss.css" => ".root {
386+
color: red;
387+
font-size: 14px;
388+
}
389+
390+
.highlighted {
391+
background-color: yellow;
392+
}",
393+
"/fake/output/css/classes-and-exports.module.scss.js" => "module.exports = require(\\"./classes-and-exports.module.scss.css\\");
394+
module.exports.default = module.exports;",
395+
}
396+
`;
397+
282398
exports[`SassProcessor error reporting emits an error for invalid SCSS syntax: terminal-output 1`] = `
283399
Array [
284400
"[verbose] Checking for changes to 1 files...[n]",

0 commit comments

Comments
 (0)