@@ -17,27 +17,38 @@ async function main() {
17
17
config . packages . map ( pkgPath => findAllEntryPointsAndExportedModules ( pkgPath ) ) ,
18
18
) ;
19
19
20
- const exports = packages
20
+ const allExports = packages
21
21
. map ( p => p . moduleExports )
22
22
. flat ( )
23
- . filter ( e => ! config . skipEntryPoints . includes ( e . importPath ) ) ;
23
+ . filter ( e => ! config . skipEntryPoints . includes ( e . importPath ) )
24
+ . sort ( ( a , b ) => JSON . stringify ( a ) . localeCompare ( JSON . stringify ( b ) ) ) ;
24
25
25
- const testFile = `
26
- import {NgModule, Component} from '@angular/core';
27
- ${ exports . map ( e => `import {${ e . symbolName } } from '${ e . importPath } ';` ) . join ( '\n' ) }
26
+ // Distribute the exports based on the current test shard.
27
+ // Controlled via Bazel's `shard_count` attribute. See:
28
+ // https://bazel.build/reference/test-encyclopedia#initial-conditions.
29
+ const testShardIndex =
30
+ process . env [ 'TEST_SHARD_INDEX' ] !== undefined ? Number ( process . env [ 'TEST_SHARD_INDEX' ] ) : 0 ;
31
+ const testMaxShards =
32
+ process . env [ 'TEST_TOTAL_SHARDS' ] !== undefined ? Number ( process . env [ 'TEST_TOTAL_SHARDS' ] ) : 1 ;
33
+ const testChunkSize = Math . ceil ( allExports . length / testMaxShards ) ;
34
+ const testChunkStart = testChunkSize * testShardIndex ;
35
+ const shardExports = allExports . slice ( testChunkStart , testChunkStart + testChunkSize ) ;
28
36
29
- @NgModule({
30
- exports: [
31
- ${ exports . map ( e => e . symbolName ) . join ( ', ' ) }
32
- ]
33
- })
34
- export class TestModule {}
37
+ const testFiles = shardExports . map ( e => ( {
38
+ content : `
39
+ import {NgModule, Component} from '@angular/core';
40
+ import {${ e . symbolName } } from '${ e . importPath } ';
35
41
36
- @Component({imports: [TestModule], template: ''})
37
- export class TestComponent {}
38
- ` ;
42
+ @NgModule({
43
+ exports: [${ e . symbolName } ]
44
+ })
45
+ export class TestModule {}
39
46
40
- await fs . writeFile ( path . join ( tmpDir , 'test.ts' ) , testFile ) ;
47
+ @Component({imports: [TestModule], template: ''})
48
+ export class TestComponent {}
49
+ ` ,
50
+ path : path . join ( tmpDir , `${ e . symbolName . toLowerCase ( ) } .ts` ) ,
51
+ } ) ) ;
41
52
42
53
// Prepare node modules to resolve e.g. `@angular/core`
43
54
await fs . symlink ( path . resolve ( './node_modules' ) , path . join ( tmpDir , 'node_modules' ) ) ;
@@ -47,26 +58,34 @@ async function main() {
47
58
await fs . symlink ( path . resolve ( packagePath ) , `./node_modules/${ name } ` ) ;
48
59
}
49
60
50
- const result = performCompilation ( {
51
- options : {
52
- rootDir : tmpDir ,
53
- skipLibCheck : true ,
54
- noEmit : true ,
55
- module : ts . ModuleKind . ESNext ,
56
- moduleResolution : ts . ModuleResolutionKind . Bundler ,
57
- strictTemplates : true ,
58
- preserveSymlinks : true ,
59
- strict : true ,
60
- // Note: HMR is needed as it will disable the Angular compiler's tree-shaking of used
61
- // directives/components. This is critical for this test as it allows us to simply all
62
- // modules and automatically validate that all symbols are reachable/importable.
63
- _enableHmr : true ,
64
- } ,
65
- rootNames : [ path . join ( tmpDir , 'test.ts' ) ] ,
66
- } ) ;
61
+ const diagnostics : ts . Diagnostic [ ] = [ ] ;
62
+
63
+ for ( const testFile of testFiles ) {
64
+ await fs . writeFile ( testFile . path , testFile . content ) ;
65
+
66
+ const result = performCompilation ( {
67
+ options : {
68
+ rootDir : tmpDir ,
69
+ skipLibCheck : true ,
70
+ noEmit : true ,
71
+ module : ts . ModuleKind . ESNext ,
72
+ moduleResolution : ts . ModuleResolutionKind . Bundler ,
73
+ strictTemplates : true ,
74
+ preserveSymlinks : true ,
75
+ strict : true ,
76
+ // Note: HMR is needed as it will disable the Angular compiler's tree-shaking of used
77
+ // directives/components. This is critical for this test as it allows us to simply all
78
+ // modules and automatically validate that all symbols are reachable/importable.
79
+ _enableHmr : true ,
80
+ } ,
81
+ rootNames : [ testFile . path ] ,
82
+ } ) ;
83
+
84
+ diagnostics . push ( ...result . diagnostics ) ;
85
+ }
67
86
68
87
console . error (
69
- ts . formatDiagnosticsWithColorAndContext ( result . diagnostics , {
88
+ ts . formatDiagnosticsWithColorAndContext ( diagnostics , {
70
89
getCanonicalFileName : f => f ,
71
90
getCurrentDirectory : ( ) => '/' ,
72
91
getNewLine : ( ) => '\n' ,
@@ -75,7 +94,7 @@ async function main() {
75
94
76
95
await fs . rm ( tmpDir , { recursive : true , force : true , maxRetries : 2 } ) ;
77
96
78
- if ( result . diagnostics . length > 0 ) {
97
+ if ( diagnostics . length > 0 ) {
79
98
process . exitCode = 1 ;
80
99
}
81
100
}
0 commit comments