1
1
import assert from 'node:assert/strict' ;
2
- import * as fs from 'node:fs' ;
3
- import { expectFileToExist , expectFileToMatch , writeFile } from '../../utils/fs' ;
2
+ import { writeFile , stat , mkdir , symlink , utimes } from 'node:fs/promises ' ;
3
+ import { expectFileToExist , expectFileToMatch } from '../../utils/fs' ;
4
4
import { ng } from '../../utils/process' ;
5
5
import { updateJsonFile } from '../../utils/project' ;
6
6
import { expectToFail } from '../../utils/utils' ;
@@ -9,21 +9,31 @@ import { getGlobalVariable } from '../../utils/env';
9
9
const isNodeV22orHigher = Number ( process . versions . node . split ( '.' , 1 ) [ 0 ] ) >= 22 ;
10
10
11
11
export default async function ( ) {
12
+ // Update the atime and mtime of the original file.
13
+ // Note: Node.js has different time precision, which may cause mtime-based tests to fail.
14
+ // Ensure both values are rounded to the same precision for consistency.
15
+ // Example:
16
+ // Original: '1742973507738.0234'
17
+ // Node.js CP: '1742973507737.999'
18
+ const { atime, mtime } = await stat ( 'public/favicon.ico' ) ;
19
+ await utimes ( 'public/favicon.ico' , atime , mtime ) ;
20
+
12
21
await writeFile ( 'public/.file' , '' ) ;
13
22
await writeFile ( 'public/test.abc' , 'hello world' ) ;
14
23
15
- const originalStats = fs . statSync ( 'public/favicon.ico' , { bigint : true } ) ;
16
-
17
24
await ng ( 'build' , '--configuration=development' ) ;
18
-
19
25
await expectFileToExist ( 'dist/test-project/browser/favicon.ico' ) ;
20
26
await expectFileToExist ( 'dist/test-project/browser/.file' ) ;
21
27
await expectFileToMatch ( 'dist/test-project/browser/test.abc' , 'hello world' ) ;
22
28
await expectToFail ( ( ) => expectFileToExist ( 'dist/test-project/browser/.gitkeep' ) ) ;
23
29
24
30
// Timestamp preservation only supported with application build system on Node.js v22+
25
31
if ( isNodeV22orHigher && getGlobalVariable ( 'argv' ) [ 'esbuild' ] ) {
26
- const outputStats = fs . statSync ( 'dist/test-project/browser/favicon.ico' , { bigint : true } ) ;
32
+ const [ originalStats , outputStats ] = await Promise . all ( [
33
+ stat ( 'public/favicon.ico' ) ,
34
+ stat ( 'dist/test-project/browser/favicon.ico' ) ,
35
+ ] ) ;
36
+
27
37
assert . equal (
28
38
originalStats . mtimeMs ,
29
39
outputStats . mtimeMs ,
@@ -38,13 +48,17 @@ export default async function () {
38
48
{ glob : '**/*' , input : 'public' , followSymlinks : true } ,
39
49
] ;
40
50
} ) ;
41
- fs . mkdirSync ( 'dirToSymlink/subdir1' , { recursive : true } ) ;
42
- fs . mkdirSync ( 'dirToSymlink/subdir2/subsubdir1' , { recursive : true } ) ;
43
- fs . writeFileSync ( 'dirToSymlink/a.txt' , '' ) ;
44
- fs . writeFileSync ( 'dirToSymlink/subdir1/b.txt' , '' ) ;
45
- fs . writeFileSync ( 'dirToSymlink/subdir2/c.txt' , '' ) ;
46
- fs . writeFileSync ( 'dirToSymlink/subdir2/subsubdir1/d.txt' , '' ) ;
47
- fs . symlinkSync ( process . cwd ( ) + '/dirToSymlink' , 'public/symlinkDir' ) ;
51
+
52
+ await mkdir ( 'dirToSymlink/subdir1' , { recursive : true } ) ;
53
+ await mkdir ( 'dirToSymlink/subdir2/subsubdir1' , { recursive : true } ) ;
54
+ await symlink ( process . cwd ( ) + '/dirToSymlink' , 'public/symlinkDir' ) ;
55
+
56
+ await Promise . all ( [
57
+ writeFile ( 'dirToSymlink/a.txt' , '' ) ,
58
+ writeFile ( 'dirToSymlink/subdir1/b.txt' , '' ) ,
59
+ writeFile ( 'dirToSymlink/subdir2/c.txt' , '' ) ,
60
+ writeFile ( 'dirToSymlink/subdir2/subsubdir1/d.txt' , '' ) ,
61
+ ] ) ;
48
62
49
63
await ng ( 'build' , '--configuration=development' ) ;
50
64
0 commit comments