@@ -178,43 +178,43 @@ describe('Deterministic JSON Serialization', () => {
178178 } )
179179
180180 describe ( 'Preprocessing Logic' , ( ) => {
181- it ( 'should remove docker_compose_file when runner is bash' , ( ) => {
181+ it ( 'should remove docker_compose_file when runner is bash (with normalization) ' , ( ) => {
182182 const compose : AppCompose = {
183183 runner : "bash" ,
184184 bash_script : "start.sh" ,
185185 docker_compose_file : "docker-compose.yml"
186186 }
187187
188- const hash = getComposeHash ( compose )
188+ const hash = getComposeHash ( compose , true )
189189
190190 // Should be the same as compose without docker_compose_file
191191 const compose2 : AppCompose = {
192192 runner : "bash" ,
193193 bash_script : "start.sh"
194194 }
195195
196- expect ( hash ) . toBe ( getComposeHash ( compose2 ) )
196+ expect ( hash ) . toBe ( getComposeHash ( compose2 , true ) )
197197 } )
198198
199- it ( 'should remove bash_script when runner is docker-compose' , ( ) => {
199+ it ( 'should remove bash_script when runner is docker-compose (with normalization) ' , ( ) => {
200200 const compose : AppCompose = {
201201 runner : "docker-compose" ,
202202 docker_compose_file : "docker-compose.yml" ,
203203 bash_script : "start.sh"
204204 }
205205
206- const hash = getComposeHash ( compose )
206+ const hash = getComposeHash ( compose , true )
207207
208208 // Should be the same as compose without bash_script
209209 const compose2 : AppCompose = {
210210 runner : "docker-compose" ,
211211 docker_compose_file : "docker-compose.yml"
212212 }
213213
214- expect ( hash ) . toBe ( getComposeHash ( compose2 ) )
214+ expect ( hash ) . toBe ( getComposeHash ( compose2 , true ) )
215215 } )
216216
217- it ( 'should remove empty pre_launch_script' , ( ) => {
217+ it ( 'should remove empty pre_launch_script (with normalization) ' , ( ) => {
218218 const compose1 : AppCompose = {
219219 runner : "docker-compose" ,
220220 docker_compose_file : "docker-compose.yml" ,
@@ -226,10 +226,10 @@ describe('Deterministic JSON Serialization', () => {
226226 docker_compose_file : "docker-compose.yml"
227227 }
228228
229- expect ( getComposeHash ( compose1 ) ) . toBe ( getComposeHash ( compose2 ) )
229+ expect ( getComposeHash ( compose1 , true ) ) . toBe ( getComposeHash ( compose2 , true ) )
230230 } )
231231
232- it ( 'should keep non-empty pre_launch_script' , ( ) => {
232+ it ( 'should keep non-empty pre_launch_script (with normalization) ' , ( ) => {
233233 const compose1 : AppCompose = {
234234 runner : "docker-compose" ,
235235 docker_compose_file : "docker-compose.yml" ,
@@ -241,7 +241,7 @@ describe('Deterministic JSON Serialization', () => {
241241 docker_compose_file : "docker-compose.yml"
242242 }
243243
244- expect ( getComposeHash ( compose1 ) ) . not . toBe ( getComposeHash ( compose2 ) )
244+ expect ( getComposeHash ( compose1 , true ) ) . not . toBe ( getComposeHash ( compose2 , true ) )
245245 } )
246246 } )
247247
@@ -299,7 +299,7 @@ describe('Deterministic JSON Serialization', () => {
299299 // @ts -expect-error - empty object is valid
300300 const compose : AppCompose = { }
301301 const hash = getComposeHash ( compose )
302-
302+
303303 expect ( hash ) . toHaveLength ( 64 )
304304 expect ( hash ) . toMatch ( / ^ [ a - f 0 - 9 ] { 64 } $ / )
305305 } )
@@ -475,84 +475,51 @@ describe('Deterministic JSON Serialization', () => {
475475 } )
476476 } )
477477
478- describe ( 'Default Values Processing ' , ( ) => {
479- it ( 'should set default values for undefined fields ' , ( ) => {
478+ describe ( 'Normalize Parameter ' , ( ) => {
479+ it ( 'should skip preprocessing when normalize=false (default) ' , ( ) => {
480480 const compose : AppCompose = {
481- runner : "docker-compose" ,
481+ runner : "bash" ,
482+ bash_script : "start.sh" ,
482483 docker_compose_file : "docker-compose.yml"
483484 }
484485
485- const hash1 = getComposeHash ( compose )
486+ const hashWithoutNormalize = getComposeHash ( compose )
487+ const hashExplicitFalse = getComposeHash ( compose , false )
486488
487- // Should be the same as explicitly setting defaults (but empty arrays/objects are removed)
488- const compose2 : AppCompose = {
489- manifest_version : 1 ,
490- runner : "docker-compose" ,
491- docker_compose_file : "docker-compose.yml" ,
492- public_logs : false ,
493- public_sysinfo : false ,
494- public_tcbinfo : true ,
495- kms_enabled : false ,
496- gateway_enabled : false ,
497- local_key_provider_enabled : false ,
498- no_instance_id : false ,
499- secure_time : true
500- // Empty arrays and objects are removed: features, docker_config, key_provider_id, allowed_envs, name
501- }
502-
503- expect ( hash1 ) . toBe ( getComposeHash ( compose2 ) )
489+ expect ( hashWithoutNormalize ) . toBe ( hashExplicitFalse )
504490 } )
505- } )
506491
507- describe ( 'Gateway/Tproxy Enabled Logic' , ( ) => {
508- it ( 'should handle tproxy_enabled conversion to gateway_enabled' , ( ) => {
509- const compose1 : AppCompose = {
510- runner : "docker-compose" ,
511- docker_compose_file : "docker-compose.yml" ,
512- tproxy_enabled : true
492+ it ( 'should apply preprocessing when normalize=true' , ( ) => {
493+ const compose : AppCompose = {
494+ runner : "bash" ,
495+ bash_script : "start.sh" ,
496+ docker_compose_file : "docker-compose.yml"
513497 }
514498
515- const compose2 : AppCompose = {
516- manifest_version : 1 ,
517- runner : "docker-compose" ,
518- docker_compose_file : "docker-compose.yml" ,
519- gateway_enabled : true ,
520- public_logs : false ,
521- public_sysinfo : false ,
522- public_tcbinfo : true ,
523- kms_enabled : false ,
524- local_key_provider_enabled : false ,
525- no_instance_id : false ,
526- secure_time : true
527- }
499+ const hashWithNormalize = getComposeHash ( compose , true )
500+ const hashWithoutNormalize = getComposeHash ( compose , false )
528501
529- expect ( getComposeHash ( compose1 ) ) . toBe ( getComposeHash ( compose2 ) )
502+ // These should be different because preprocessing is applied only with normalize=true
503+ expect ( hashWithNormalize ) . not . toBe ( hashWithoutNormalize )
530504 } )
531505
532- it ( 'should prioritize gateway_enabled over tproxy_enabled ' , ( ) => {
533- const compose1 : AppCompose = {
506+ it ( 'should handle empty pre_launch_script differently with/without normalization ' , ( ) => {
507+ const compose : AppCompose = {
534508 runner : "docker-compose" ,
535509 docker_compose_file : "docker-compose.yml" ,
536- gateway_enabled : false ,
537- tproxy_enabled : true
510+ pre_launch_script : ""
538511 }
539512
540- // Should result in gateway_enabled: true because tproxy_enabled is true
541- const compose2 : AppCompose = {
542- manifest_version : 1 ,
513+ const composeWithoutEmpty : AppCompose = {
543514 runner : "docker-compose" ,
544- docker_compose_file : "docker-compose.yml" ,
545- gateway_enabled : true ,
546- public_logs : false ,
547- public_sysinfo : false ,
548- public_tcbinfo : true ,
549- kms_enabled : false ,
550- local_key_provider_enabled : false ,
551- no_instance_id : false ,
552- secure_time : true
515+ docker_compose_file : "docker-compose.yml"
553516 }
554517
555- expect ( getComposeHash ( compose1 ) ) . toBe ( getComposeHash ( compose2 ) )
518+ // With normalization, empty pre_launch_script should be removed
519+ expect ( getComposeHash ( compose , true ) ) . toBe ( getComposeHash ( composeWithoutEmpty , true ) )
520+
521+ // Without normalization, empty pre_launch_script should remain
522+ expect ( getComposeHash ( compose , false ) ) . not . toBe ( getComposeHash ( composeWithoutEmpty , false ) )
556523 } )
557524 } )
558525
@@ -574,7 +541,7 @@ describe('Deterministic JSON Serialization', () => {
574541 const compose : AppCompose = {
575542 runner : "docker-compose" ,
576543 docker_compose_file : "docker-compose.yml" ,
577- bash_script : "start.sh" , // Should be removed by preprocessing
544+ bash_script : "start.sh" , // Should be removed by preprocessing when normalize=true
578545 features : [ "legacy-feature" ] ,
579546 public_logs : true ,
580547 kms_enabled : false ,
0 commit comments