@@ -19,6 +19,9 @@ function getDefaultArgv() {
1919// Stable absolute path used as the resolved ui5DataDir in most tests
2020const TEST_UI5_DATA_DIR = path . resolve ( "/test/ui5/home" ) ;
2121
22+ // Typical framework stub result shape
23+ const FRAMEWORK_STUB = { path : "framework" , projectCount : 2 , libraryCount : 18 , versionCount : 5 } ;
24+
2225test . beforeEach ( async ( t ) => {
2326 t . context . argv = getDefaultArgv ( ) ;
2427 t . context . stderrWriteStub = sinon . stub ( process . stderr , "write" ) ;
@@ -108,7 +111,6 @@ test.serial("ui5 cache clean: falls back to ~/.ui5 when getUi5DataDir returns un
108111 const { cache, argv, getUi5DataDirStub, frameworkCacheGetCacheInfo, buildCacheGetCacheInfo,
109112 stderrWriteStub} = t . context ;
110113
111- // Simulate no env var, no config — getUi5DataDir returns undefined
112114 getUi5DataDirStub . resolves ( undefined ) ;
113115 frameworkCacheGetCacheInfo . resolves ( null ) ;
114116 buildCacheGetCacheInfo . resolves ( null ) ;
@@ -118,11 +120,7 @@ test.serial("ui5 cache clean: falls back to ~/.ui5 when getUi5DataDir returns un
118120
119121 const expectedDefault = path . join ( os . homedir ( ) , ".ui5" ) ;
120122 const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
121- t . true ( allOutput . includes ( expectedDefault ) ,
122- "Falls back to ~/.ui5 and shows it in checking line" ) ;
123-
124- // getCacheInfo called with the default path
125- t . is ( frameworkCacheGetCacheInfo . callCount , 1 , "getCacheInfo called" ) ;
123+ t . true ( allOutput . includes ( expectedDefault ) , "Falls back to ~/.ui5 and shows it in checking line" ) ;
126124 t . is ( frameworkCacheGetCacheInfo . firstCall . args [ 0 ] , expectedDefault ,
127125 "getCacheInfo receives ~/.ui5 as ui5DataDir" ) ;
128126} ) ;
@@ -136,18 +134,14 @@ test.serial("ui5 cache clean: uses resolved path from getUi5DataDir", async (t)
136134 argv [ "_" ] = [ "cache" , "clean" ] ;
137135 await cache . handler ( argv ) ;
138136
139- // The stub returns TEST_UI5_DATA_DIR — verify it was passed to getCacheInfo
140137 t . is ( frameworkCacheGetCacheInfo . firstCall . args [ 0 ] , TEST_UI5_DATA_DIR ,
141138 "getCacheInfo receives the path returned by getUi5DataDir" ) ;
142139
143140 const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
144- t . true ( allOutput . includes ( TEST_UI5_DATA_DIR ) ,
145- "Resolved ui5DataDir shown in checking line" ) ;
141+ t . true ( allOutput . includes ( TEST_UI5_DATA_DIR ) , "Resolved ui5DataDir shown in checking line" ) ;
146142} ) ;
147143
148144test . serial ( "ui5 cache clean: relative path from config is resolved via getUi5DataDir" , async ( t ) => {
149- // getUi5DataDir already resolves relative paths against cwd — verify the cache
150- // command uses the already-resolved absolute path rather than doing its own resolution.
151145 const { cache, argv, getUi5DataDirStub, frameworkCacheGetCacheInfo, buildCacheGetCacheInfo} = t . context ;
152146
153147 const resolvedPath = path . resolve ( process . cwd ( ) , "./custom-cache" ) ;
@@ -177,20 +171,20 @@ test.serial("ui5 cache clean: nothing to clean", async (t) => {
177171 const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
178172 t . true ( allOutput . includes ( "Checking cache at" ) , "Prints checking line" ) ;
179173 t . true ( allOutput . includes ( "Nothing to clean" ) , "Prints nothing to clean" ) ;
180- t . is ( frameworkCacheCleanCache . callCount , 0 , "frameworkCache.cleanCache should not be called" ) ;
181- t . is ( buildCacheCleanCache . callCount , 0 , "buildCache.cleanCache should not be called" ) ;
174+ t . is ( frameworkCacheCleanCache . callCount , 0 , "frameworkCache.cleanCache not called" ) ;
175+ t . is ( buildCacheCleanCache . callCount , 0 , "buildCache.cleanCache not called" ) ;
182176} ) ;
183177
184178test . serial ( "ui5 cache clean: removes both entries and reports" , async ( t ) => {
185179 const { cache, argv, stderrWriteStub, frameworkCacheCleanCache, frameworkCacheGetCacheInfo,
186180 buildCacheCleanCache, buildCacheGetCacheInfo, yesnoStub} = t . context ;
187181
188- frameworkCacheGetCacheInfo . resolves ( { path : "framework" , count : 340 } ) ;
182+ frameworkCacheGetCacheInfo . resolves ( FRAMEWORK_STUB ) ;
189183 buildCacheGetCacheInfo . resolves ( { path : "buildCache/v0_7" , size : 8 * 1024 * 1024 } ) ;
190184
191185 yesnoStub . resolves ( true ) ;
192186
193- frameworkCacheCleanCache . resolves ( { path : "framework" , count : 340 } ) ;
187+ frameworkCacheCleanCache . resolves ( FRAMEWORK_STUB ) ;
194188 buildCacheCleanCache . resolves ( { path : "buildCache/v0_7" , size : 7 * 1024 * 1024 } ) ; // VACUUM freed less
195189
196190 argv [ "_" ] = [ "cache" , "clean" ] ;
@@ -202,25 +196,26 @@ test.serial("ui5 cache clean: removes both entries and reports", async (t) => {
202196
203197 const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
204198
205- // Checking line with absolute path
199+ // Checking line
206200 t . true ( allOutput . includes ( "Checking cache at" ) , "Prints checking line" ) ;
207201 t . true ( allOutput . includes ( TEST_UI5_DATA_DIR ) , "Shows resolved ui5DataDir" ) ;
208202
209- // Listing shows absolute paths
203+ // Absolute paths in listing
210204 const expectedFrameworkAbs = path . join ( TEST_UI5_DATA_DIR , "framework" ) ;
211205 const expectedBuildAbs = path . join ( TEST_UI5_DATA_DIR , "buildCache/v0_7" ) ;
212206 t . true ( allOutput . includes ( expectedFrameworkAbs ) , "Shows absolute framework path" ) ;
213207 t . true ( allOutput . includes ( expectedBuildAbs ) , "Shows absolute build cache path" ) ;
214208
215- // Labels and detail
216- t . true ( allOutput . includes ( "UI5 Framework packages" ) , "Shows framework label" ) ;
217- t . true ( allOutput . includes ( "Build cache (DB)" ) , "Shows build cache label" ) ;
218- t . true ( allOutput . includes ( "340 files" ) , "Shows framework file count" ) ;
219- t . true ( allOutput . includes ( "8.0 MB" ) , "Shows build cache pre-clean size" ) ;
220- t . false ( allOutput . includes ( "7.0 MB" ) , "Does not show VACUUM-freed size (pre-clean size reused)" ) ;
221- t . false ( allOutput . includes ( "Total:" ) , "Does not show total line" ) ;
209+ // Framework detail: projects, libraries, versions
210+ t . true ( allOutput . includes ( "2 projects" ) , "Shows project count" ) ;
211+ t . true ( allOutput . includes ( "18 libraries" ) , "Shows library count" ) ;
212+ t . true ( allOutput . includes ( "5 versions" ) , "Shows version count" ) ;
222213
223- // Success
214+ // Build cache detail: pre-clean size reused (not VACUUM-freed 7 MB)
215+ t . true ( allOutput . includes ( "8.0 MB" ) , "Shows pre-clean build cache size" ) ;
216+ t . false ( allOutput . includes ( "7.0 MB" ) , "Does not show VACUUM-freed size" ) ;
217+
218+ t . false ( allOutput . includes ( "Total:" ) , "Does not show total line" ) ;
224219 t . true ( allOutput . includes ( "Cleaned UI5 Framework packages and Build cache (DB)" ) ,
225220 "Shows success summary" ) ;
226221} ) ;
@@ -229,9 +224,8 @@ test.serial("ui5 cache clean: user cancels", async (t) => {
229224 const { cache, argv, stderrWriteStub, frameworkCacheCleanCache, frameworkCacheGetCacheInfo,
230225 buildCacheCleanCache, buildCacheGetCacheInfo, yesnoStub} = t . context ;
231226
232- frameworkCacheGetCacheInfo . resolves ( { path : "framework" , count : 10 } ) ;
227+ frameworkCacheGetCacheInfo . resolves ( FRAMEWORK_STUB ) ;
233228 buildCacheGetCacheInfo . resolves ( null ) ;
234-
235229 yesnoStub . resolves ( false ) ;
236230
237231 argv [ "_" ] = [ "cache" , "clean" ] ;
@@ -246,24 +240,45 @@ test.serial("ui5 cache clean: user cancels", async (t) => {
246240 t . false ( allOutput . includes ( "Success" ) , "Does not show success message" ) ;
247241} ) ;
248242
249- test . serial ( "ui5 cache clean: framework only" , async ( t ) => {
243+ test . serial ( "ui5 cache clean: framework only — singular labels " , async ( t ) => {
250244 const { cache, argv, stderrWriteStub, frameworkCacheCleanCache, frameworkCacheGetCacheInfo,
251245 buildCacheGetCacheInfo, yesnoStub} = t . context ;
252246
253- frameworkCacheGetCacheInfo . resolves ( { path : "framework" , count : 1 } ) ;
247+ const singleStub = { path : "framework" , projectCount : 1 , libraryCount : 1 , versionCount : 1 } ;
248+ frameworkCacheGetCacheInfo . resolves ( singleStub ) ;
254249 buildCacheGetCacheInfo . resolves ( null ) ;
255250 yesnoStub . resolves ( true ) ;
256- frameworkCacheCleanCache . resolves ( { path : "framework" , count : 1 } ) ;
251+ frameworkCacheCleanCache . resolves ( singleStub ) ;
257252
258253 argv [ "_" ] = [ "cache" , "clean" ] ;
259254 await cache . handler ( argv ) ;
260255
261256 const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
262- t . true ( allOutput . includes ( "1 file" ) , "Uses singular 'file'" ) ;
257+ t . true ( allOutput . includes ( "1 project," ) , "Uses singular 'project'" ) ;
258+ t . true ( allOutput . includes ( "1 library," ) , "Uses singular 'library'" ) ;
259+ t . true ( allOutput . includes ( "1 version" ) , "Uses singular 'version'" ) ;
263260 t . false ( allOutput . includes ( "Build cache (DB)" ) , "Does not mention build cache" ) ;
264261 t . true ( allOutput . includes ( "Cleaned UI5 Framework packages" ) , "Success mentions framework only" ) ;
265262} ) ;
266263
264+ test . serial ( "ui5 cache clean: framework only — plural labels" , async ( t ) => {
265+ const { cache, argv, stderrWriteStub, frameworkCacheCleanCache, frameworkCacheGetCacheInfo,
266+ buildCacheGetCacheInfo, yesnoStub} = t . context ;
267+
268+ frameworkCacheGetCacheInfo . resolves ( FRAMEWORK_STUB ) ;
269+ buildCacheGetCacheInfo . resolves ( null ) ;
270+ yesnoStub . resolves ( true ) ;
271+ frameworkCacheCleanCache . resolves ( FRAMEWORK_STUB ) ;
272+
273+ argv [ "_" ] = [ "cache" , "clean" ] ;
274+ await cache . handler ( argv ) ;
275+
276+ const allOutput = stderrWriteStub . args . map ( ( a ) => a [ 0 ] ) . join ( "" ) ;
277+ t . true ( allOutput . includes ( "2 projects" ) , "Uses plural 'projects'" ) ;
278+ t . true ( allOutput . includes ( "18 libraries" ) , "Uses plural 'libraries'" ) ;
279+ t . true ( allOutput . includes ( "5 versions" ) , "Uses plural 'versions'" ) ;
280+ } ) ;
281+
267282test . serial ( "ui5 cache clean: build only" , async ( t ) => {
268283 const { cache, argv, stderrWriteStub,
269284 buildCacheCleanCache, buildCacheGetCacheInfo, yesnoStub} = t . context ;
@@ -317,9 +332,9 @@ test.serial("ui5 cache clean --yes: skips confirmation prompt", async (t) => {
317332 const { cache, argv, stderrWriteStub, frameworkCacheCleanCache, frameworkCacheGetCacheInfo,
318333 buildCacheCleanCache, buildCacheGetCacheInfo, yesnoStub} = t . context ;
319334
320- frameworkCacheGetCacheInfo . resolves ( { path : "framework" , count : 100 } ) ;
335+ frameworkCacheGetCacheInfo . resolves ( FRAMEWORK_STUB ) ;
321336 buildCacheGetCacheInfo . resolves ( { path : "buildCache/v0_7" , size : 5 * 1024 * 1024 } ) ;
322- frameworkCacheCleanCache . resolves ( { path : "framework" , count : 100 } ) ;
337+ frameworkCacheCleanCache . resolves ( FRAMEWORK_STUB ) ;
323338 buildCacheCleanCache . resolves ( { path : "buildCache/v0_7" , size : 5 * 1024 * 1024 } ) ;
324339
325340 argv [ "_" ] = [ "cache" , "clean" ] ;
0 commit comments