@@ -4,6 +4,7 @@ import log from 'lighthouse-logger';
44import type Details from 'lighthouse/types/lhr/audit-details' ;
55import type { Result } from 'lighthouse/types/lhr/audit-result' ;
66import { vol } from 'memfs' ;
7+ import os from 'node:os' ;
78import path from 'node:path' ;
89import { beforeEach , describe , expect , it , vi } from 'vitest' ;
910import {
@@ -22,6 +23,7 @@ import {
2223 getConfig ,
2324 normalizeAuditOutputs ,
2425 toAuditOutputs ,
26+ withLocalTmpDir ,
2527} from './utils.js' ;
2628
2729// mock bundleRequire inside importEsmModule used for fetching config
@@ -502,3 +504,63 @@ describe('enrichFlags', () => {
502504 } ) ;
503505 } ) ;
504506} ) ;
507+
508+ describe ( 'withLocalTmpDir' , ( ) => {
509+ it ( 'should return unchanged function on Linux' , ( ) => {
510+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'linux' ) ;
511+ const runner = vi . fn ( ) . mockResolvedValue ( 'result' ) ;
512+
513+ expect ( withLocalTmpDir ( runner ) ) . toBe ( runner ) ;
514+ } ) ;
515+
516+ it ( 'should return unchanged function on MacOS' , ( ) => {
517+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'darwin' ) ;
518+ const runner = vi . fn ( ) . mockResolvedValue ( 'result' ) ;
519+
520+ expect ( withLocalTmpDir ( runner ) ) . toBe ( runner ) ;
521+ } ) ;
522+
523+ it ( 'should wrap function on Windows' , async ( ) => {
524+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'win32' ) ;
525+ const runner = vi . fn ( ) . mockResolvedValue ( 'result' ) ;
526+
527+ const transformed = withLocalTmpDir ( runner ) ;
528+
529+ expect ( transformed ) . not . toBe ( runner ) ;
530+ await expect ( transformed ( ) ) . resolves . toBe ( 'result' ) ;
531+ expect ( runner ) . toHaveBeenCalled ( ) ;
532+ } ) ;
533+
534+ it ( 'should override TEMP environment variable before function call' , async ( ) => {
535+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'win32' ) ;
536+ const runner = vi
537+ . fn ( )
538+ . mockImplementation (
539+ async ( ) => `TEMP directory is ${ process . env [ 'TEMP' ] } ` ,
540+ ) ;
541+
542+ await expect ( withLocalTmpDir ( runner ) ( ) ) . resolves . toBe (
543+ `TEMP directory is ${ path . join ( 'node_modules' , '.code-pushup' , 'lighthouse' , 'tmp' ) } ` ,
544+ ) ;
545+ } ) ;
546+
547+ it ( 'should reset TEMP environment variable after function resolves' , async ( ) => {
548+ const originalTmpDir = String . raw `\\?\C:\Users\RUNNER~1\AppData\Local\Temp` ;
549+ const runner = vi . fn ( ) . mockResolvedValue ( 'result' ) ;
550+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'win32' ) ;
551+ vi . stubEnv ( 'TEMP' , originalTmpDir ) ;
552+
553+ await withLocalTmpDir ( runner ) ( ) ;
554+
555+ expect ( process . env [ 'TEMP' ] ) . toBe ( originalTmpDir ) ;
556+ } ) ;
557+
558+ it ( 'should reset TEMP environment variable after function rejects' , async ( ) => {
559+ const runner = vi . fn ( ) . mockRejectedValue ( 'error' ) ;
560+ vi . spyOn ( os , 'platform' ) . mockReturnValue ( 'win32' ) ;
561+ vi . stubEnv ( 'TEMP' , '' ) ;
562+
563+ await expect ( withLocalTmpDir ( runner ) ( ) ) . rejects . toBe ( 'error' ) ;
564+ expect ( process . env [ 'TEMP' ] ) . toBe ( '' ) ;
565+ } ) ;
566+ } ) ;
0 commit comments