@@ -50,104 +50,16 @@ public void Constructor_WithNullLogger_ThrowsArgumentNullException()
5050 new TypeScriptTypechecker ( mockDockerService . Object , null ! ) ) ;
5151 }
5252
53- [ Test ]
54- public void ParseImportedPackages_WithBasicImports_ReturnsExpectedPackages ( )
55- {
56- var code = @"
57- import { Client } from '@azure/storage-blob';
58- import * as fs from 'fs';
59- import './relative-file';
60- import { DefaultAzureCredential } from '@azure/identity';
61- const path = require('path');
62- " ;
63-
64- var excludedPackages = new HashSet < string > ( ) ;
65- var packages = TypeScriptTypechecker . ParseImportedPackages ( code , excludedPackages ) ;
66-
67- Assert . That ( packages , Contains . Item ( "@azure/storage-blob" ) ) ;
68- Assert . That ( packages , Contains . Item ( "@azure/identity" ) ) ;
69- Assert . That ( packages , Contains . Item ( "fs" ) ) ;
70- Assert . That ( packages , Contains . Item ( "path" ) ) ;
71- Assert . That ( packages , Contains . Item ( "typescript" ) ) ;
72- Assert . That ( packages , Contains . Item ( "@types/node" ) ) ;
73-
74- // Should not contain relative imports
75- Assert . That ( packages , Does . Not . Contain ( "./relative-file" ) ) ;
76- }
77-
78- [ Test ]
79- public void ParseImportedPackages_WithScopedPackages_ExtractsCorrectPackageRoot ( )
80- {
81- var code = @"
82- import { Client } from '@azure/storage-blob/types';
83- import { helper } from '@azure/core-auth/helpers/utils';
84- import { normalPkg } from 'normal-package/sub/path';
85- " ;
86-
87- var excludedPackages = new HashSet < string > ( ) ;
88- var packages = TypeScriptTypechecker . ParseImportedPackages ( code , excludedPackages ) ;
89-
90- Assert . That ( packages , Contains . Item ( "@azure/storage-blob" ) ) ;
91- Assert . That ( packages , Contains . Item ( "@azure/core-auth" ) ) ;
92- Assert . That ( packages , Contains . Item ( "normal-package" ) ) ;
93- }
94-
95- [ Test ]
96- public void ParseImportedPackages_WithExcludedPackages_FiltersCorrectly ( )
97- {
98- var code = @"
99- import { Client } from '@azure/storage-blob';
100- import { DefaultAzureCredential } from '@azure/identity';
101- " ;
102-
103- var excludedPackages = new HashSet < string > { "@azure/identity" } ;
104- var packages = TypeScriptTypechecker . ParseImportedPackages ( code , excludedPackages ) ;
105-
106- Assert . That ( packages , Contains . Item ( "@azure/storage-blob" ) ) ;
107- Assert . That ( packages , Does . Not . Contain ( "@azure/identity" ) ) ;
108- }
109-
110- [ Test ]
111- public void ParseImportedPackages_WithDynamicImports_ExtractsPackages ( )
112- {
113- var code = @"
114- const module = await import('@azure/storage-blob');
115- const fs = await import('fs/promises');
116- " ;
117-
118- var excludedPackages = new HashSet < string > ( ) ;
119- var packages = TypeScriptTypechecker . ParseImportedPackages ( code , excludedPackages ) ;
120-
121- Assert . That ( packages , Contains . Item ( "@azure/storage-blob" ) ) ;
122- Assert . That ( packages , Contains . Item ( "fs" ) ) ;
123- }
124-
125- [ Test ]
126- public void ParseImportedPackages_WithBarePackageNames_ExtractsCorrectly ( )
127- {
128- var code = @"
129- import fs from 'fs';
130- import path from 'path';
131- import crypto from 'crypto';
132- import { Client } from '@azure/storage-blob';
133- " ;
134-
135- var excludedPackages = new HashSet < string > ( ) ;
136- var packages = TypeScriptTypechecker . ParseImportedPackages ( code , excludedPackages ) ;
137-
138- // Verify bare package names (Node.js built-ins) are extracted correctly
139- Assert . That ( packages , Contains . Item ( "fs" ) ) ;
140- Assert . That ( packages , Contains . Item ( "path" ) ) ;
141- Assert . That ( packages , Contains . Item ( "crypto" ) ) ;
142- Assert . That ( packages , Contains . Item ( "@azure/storage-blob" ) ) ;
143- }
144-
14553 [ Test ]
14654 public async Task TypecheckAsync_WithValidCode_ReturnsSuccess ( )
14755 {
14856 // Arrange
14957 var code = "const message: string = 'Hello, World!';" ;
150- var parameters = new TypeCheckRequest ( code , null , null ) ;
58+ var parameters = new TypeCheckRequest (
59+ code ,
60+ "sample.ts" ,
61+ "/path/to/azure-sdk-for-js/sdk/keyvault/keyvault-keys" ,
62+ "/path/to/azure-sdk-for-js" ) ;
15163
15264 SetupSuccessfulDockerInteractions ( ) ;
15365
@@ -164,7 +76,11 @@ public async Task TypecheckAsync_WithFailedTypeCheck_ReturnsFailure()
16476 {
16577 // Arrange
16678 var code = "const message: string = 123; // Type error" ;
167- var parameters = new TypeCheckRequest ( code , null , null ) ;
79+ var parameters = new TypeCheckRequest (
80+ code ,
81+ "sample.ts" ,
82+ "/path/to/azure-sdk-for-js/sdk/keyvault/keyvault-keys" ,
83+ "/path/to/azure-sdk-for-js" ) ;
16884
16985 SetupFailedTypecheckInteraction ( ) ;
17086
@@ -173,43 +89,7 @@ public async Task TypecheckAsync_WithFailedTypeCheck_ReturnsFailure()
17389
17490 // Assert
17591 Assert . That ( result . Succeeded , Is . False ) ;
176- Assert . That ( result . Output , Contains . Substring ( "tsc output:" ) ) ;
177- }
178-
179- [ Test ]
180- public async Task TypecheckAsync_WithClientDist_InstallsClientPackage ( )
181- {
182- // Arrange
183- var code = "const message: string = 'Hello, World!';" ;
184- var clientDist = "/path/to/client.tgz" ;
185- var parameters = new TypeCheckRequest ( code , clientDist , null ) ;
186-
187- SetupSuccessfulDockerInteractions ( ) ;
188- SetupClientDistInstallation ( clientDist ) ;
189-
190- // Create a mock temporary file to simulate the client dist file existing
191- var tempFile = Path . GetTempFileName ( ) ;
192- try
193- {
194- await File . WriteAllTextAsync ( tempFile , "mock client dist content" ) ;
195-
196- // Update the test to use the actual temp file path
197- var parametersWithRealFile = new TypeCheckRequest ( code , tempFile , null ) ;
198-
199- // Act
200- var result = await typechecker . TypecheckAsync ( parametersWithRealFile , CancellationToken . None ) ;
201-
202- // Assert
203- Assert . That ( result . Succeeded , Is . True ) ;
204- VerifyClientDistInstallation ( tempFile ) ;
205- }
206- finally
207- {
208- if ( File . Exists ( tempFile ) )
209- {
210- File . Delete ( tempFile ) ;
211- }
212- }
92+ Assert . That ( result . Output , Contains . Substring ( "Type error" ) ) ;
21393 }
21494
21595 private void SetupSuccessfulDockerInteractions ( )
@@ -218,7 +98,12 @@ private void SetupSuccessfulDockerInteractions()
21898 var createResult = new ProcessResult { ExitCode = 0 } ;
21999 createResult . AppendStdout ( "container-id" ) ;
220100 mockDockerService . Setup ( x => x . CreateContainerAsync (
221- "node:alpine" , It . IsAny < string > ( ) , null , null , It . IsAny < CancellationToken > ( ) ) )
101+ "node:20" ,
102+ It . IsAny < string > ( ) ,
103+ It . IsAny < Dictionary < string , string > > ( ) , // environmentVars
104+ null , // workingDirectory
105+ It . IsAny < Dictionary < string , string > > ( ) , // volumeMounts
106+ It . IsAny < CancellationToken > ( ) ) )
222107 . ReturnsAsync ( createResult ) ;
223108
224109 mockDockerService . Setup ( x => x . StartContainerAsync (
@@ -229,6 +114,18 @@ private void SetupSuccessfulDockerInteractions()
229114 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
230115 . ReturnsAsync ( false ) ; // Force container creation
231116
117+ // pnpm install globally
118+ mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
119+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "install" , "-g" , "pnpm" } ) ) ,
120+ It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
121+ . ReturnsAsync ( new ProcessResult { ExitCode = 0 } ) ;
122+
123+ // turbo install globally
124+ mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
125+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "install" , "-g" , "turbo" } ) ) ,
126+ It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
127+ . ReturnsAsync ( new ProcessResult { ExitCode = 0 } ) ;
128+
232129 // File operations
233130 mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
234131 It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . Contains ( "mkdir" ) ) ,
@@ -239,93 +136,83 @@ private void SetupSuccessfulDockerInteractions()
239136 It . IsAny < string > ( ) , It . IsAny < string > ( ) , It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
240137 . ReturnsAsync ( new ProcessResult { ExitCode = 0 } ) ;
241138
242- // npm install
243- var npmInstallResult = new ProcessResult { ExitCode = 0 } ;
244- npmInstallResult . AppendStdout ( "npm install completed" ) ;
139+ // pnpm install in monorepo
140+ var pnpmInstallResult = new ProcessResult { ExitCode = 0 } ;
141+ pnpmInstallResult . AppendStdout ( "pnpm install completed" ) ;
245142 mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
246- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm " , "install" } ) ) ,
143+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "pnpm " , "install" } ) ) ,
247144 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
248- . ReturnsAsync ( npmInstallResult ) ;
145+ . ReturnsAsync ( pnpmInstallResult ) ;
249146
250- // TypeScript compilation
251- var tscResult = new ProcessResult { ExitCode = 0 } ;
252- tscResult . AppendStdout ( "Compilation successful " ) ;
147+ // turbo run build for package
148+ var turboBuildResult = new ProcessResult { ExitCode = 0 } ;
149+ turboBuildResult . AppendStdout ( "turbo build completed " ) ;
253150 mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
254- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm " , "run" , "typecheck " } ) ) ,
151+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "turbo " , "run" , "build " } ) ) ,
255152 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
256- . ReturnsAsync ( tscResult ) ;
153+ . ReturnsAsync ( turboBuildResult ) ;
257154
258- // Cleanup
155+ // build:samples
156+ var buildResult = new ProcessResult { ExitCode = 0 } ;
157+ buildResult . AppendStdout ( "Compilation successful" ) ;
259158 mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
260- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . Contains ( "rm" ) ) ,
159+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "pnpm" , "run" , "build:samples" } ) ) ,
261160 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
262- . ReturnsAsync ( new ProcessResult { ExitCode = 0 } ) ;
161+ . ReturnsAsync ( buildResult ) ;
263162 }
264163
265164 private void SetupFailedTypecheckInteraction ( )
266165 {
267166 SetupSuccessfulDockerInteractions ( ) ;
268167
269- // Override TypeScript compilation to fail
270- var failedTscResult = new ProcessResult { ExitCode = 1 } ;
271- failedTscResult . AppendStderr ( "Type error: string is not assignable to number" ) ;
272- mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
273- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "run" , "typecheck" } ) ) ,
274- It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
275- . ReturnsAsync ( failedTscResult ) ;
276- }
277-
278- private void SetupClientDistInstallation ( string clientDist )
279- {
280- // Client dist installation
281- var installResult = new ProcessResult { ExitCode = 0 } ;
282- installResult . AppendStdout ( "Client package installed" ) ;
168+ // Override build:samples to fail
169+ var failedBuildResult = new ProcessResult { ExitCode = 1 } ;
170+ failedBuildResult . AppendStderr ( "Type error: string is not assignable to number" ) ;
283171 mockDockerService . Setup ( x => x . RunCommandInContainerAsync (
284- It . IsAny < string > ( ) , It . Is < string [ ] > ( args =>
285- args . Length >= 4 && args [ 0 ] == "npm" && args [ 1 ] == "install" && args [ 2 ] == "--no-save" ) ,
172+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "pnpm" , "run" , "build:samples" } ) ) ,
286173 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) )
287- . ReturnsAsync ( installResult ) ;
174+ . ReturnsAsync ( failedBuildResult ) ;
288175 }
289176
290177 private void VerifyDockerInteractionSequence ( )
291178 {
292- // Verify container creation
179+ // Verify container creation with volume mounts and environment vars
293180 mockDockerService . Verify ( x => x . CreateContainerAsync (
294- "node:alpine" , It . IsAny < string > ( ) , null , null , It . IsAny < CancellationToken > ( ) ) ,
181+ "node:20" ,
182+ It . IsAny < string > ( ) ,
183+ It . IsAny < Dictionary < string , string > > ( ) , // environmentVars
184+ null , // workingDirectory
185+ It . IsAny < Dictionary < string , string > > ( ) , // volumeMounts
186+ It . IsAny < CancellationToken > ( ) ) ,
295187 Times . Once ) ;
296188
297- // Verify npm install
189+ // Verify pnpm install globally
298190 mockDockerService . Verify ( x => x . RunCommandInContainerAsync (
299- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "install" } ) ) ,
191+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "install" , "-g" , "pnpm" } ) ) ,
300192 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
301193 Times . Once ) ;
302194
303- // Verify TypeScript compilation
195+ // Verify turbo install globally
304196 mockDockerService . Verify ( x => x . RunCommandInContainerAsync (
305- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "run " , "typecheck " } ) ) ,
197+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "npm" , "install " , "-g" , "turbo " } ) ) ,
306198 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
307199 Times . Once ) ;
308200
309- // Verify cleanup
201+ // Verify pnpm install in monorepo
310202 mockDockerService . Verify ( x => x . RunCommandInContainerAsync (
311- It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . Contains ( "rm" ) ) ,
203+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "pnpm" , "install" } ) ) ,
312204 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
313205 Times . Once ) ;
314- }
315206
316- private void VerifyClientDistInstallation ( string clientDist )
317- {
318- var fileName = Path . GetFileName ( clientDist ) ;
319-
320- // Verify client dist copy
321- mockDockerService . Verify ( x => x . CopyToContainerAsync (
322- It . IsAny < string > ( ) , clientDist , It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
207+ // Verify turbo run build
208+ mockDockerService . Verify ( x => x . RunCommandInContainerAsync (
209+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "turbo" , "run" , "build" } ) ) ,
210+ It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
323211 Times . Once ) ;
324212
325- // Verify client dist installation
213+ // Verify build:samples
326214 mockDockerService . Verify ( x => x . RunCommandInContainerAsync (
327- It . IsAny < string > ( ) , It . Is < string [ ] > ( args =>
328- args . Length >= 4 && args [ 0 ] == "npm" && args [ 1 ] == "install" && args [ 2 ] == "--no-save" && args [ 3 ] == fileName ) ,
215+ It . IsAny < string > ( ) , It . Is < string [ ] > ( args => args . SequenceEqual ( new [ ] { "pnpm" , "run" , "build:samples" } ) ) ,
329216 It . IsAny < string > ( ) , It . IsAny < CancellationToken > ( ) ) ,
330217 Times . Once ) ;
331218 }
0 commit comments