@@ -510,3 +510,169 @@ impl ProjectLoad for NoProjectLoader {
510510 Ok ( false )
511511 }
512512}
513+
514+ #[ cfg( test) ]
515+ mod tests {
516+ use super :: * ;
517+ use crate :: canister:: recipe:: { Resolve , ResolveError } ;
518+ use crate :: manifest:: {
519+ ProjectRootLocate , ProjectRootLocateError ,
520+ canister:: { BuildSteps , SyncSteps } ,
521+ recipe:: Recipe ,
522+ } ;
523+ use camino_tempfile:: Utf8TempDir ;
524+ use indoc:: indoc;
525+
526+ struct MockProjectRootLocate {
527+ path : PathBuf ,
528+ }
529+
530+ impl MockProjectRootLocate {
531+ fn new ( path : PathBuf ) -> Self {
532+ Self { path }
533+ }
534+ }
535+
536+ impl ProjectRootLocate for MockProjectRootLocate {
537+ fn locate ( & self ) -> Result < PathBuf , ProjectRootLocateError > {
538+ Ok ( self . path . clone ( ) )
539+ }
540+ }
541+
542+ struct MockRecipeResolver ;
543+
544+ #[ async_trait]
545+ impl Resolve for MockRecipeResolver {
546+ async fn resolve ( & self , _recipe : & Recipe ) -> Result < ( BuildSteps , SyncSteps ) , ResolveError > {
547+ use crate :: manifest:: adapter:: prebuilt:: {
548+ Adapter as PrebuiltAdapter , LocalSource , SourceField ,
549+ } ;
550+ use crate :: manifest:: canister:: BuildStep ;
551+
552+ // Create a minimal BuildSteps with a dummy prebuilt step
553+ let build_steps = BuildSteps {
554+ steps : vec ! [ BuildStep :: Prebuilt ( PrebuiltAdapter {
555+ source: SourceField :: Local ( LocalSource {
556+ path: "dummy.wasm" . into( ) ,
557+ } ) ,
558+ sha256: None ,
559+ } ) ] ,
560+ } ;
561+
562+ Ok ( ( build_steps, SyncSteps :: default ( ) ) )
563+ }
564+ }
565+
566+ #[ tokio:: test]
567+ async fn test_load_minimal_project ( ) {
568+ // Create temp directory with icp.yaml
569+ let temp_dir = Utf8TempDir :: new ( ) . unwrap ( ) ;
570+ let project_dir = temp_dir. path ( ) ;
571+
572+ // Write a minimal icp.yaml
573+ let manifest_content = indoc ! { r#"
574+ canisters:
575+ - name: backend
576+ build:
577+ steps:
578+ - type: pre-built
579+ path: backend.wasm
580+ "# } ;
581+ std:: fs:: write ( project_dir. join ( "icp.yaml" ) , manifest_content) . unwrap ( ) ;
582+
583+ // Create ProjectLoadImpl with mocks
584+ let loader = ProjectLoadImpl {
585+ project_root_locate : Arc :: new ( MockProjectRootLocate :: new ( project_dir. to_path_buf ( ) ) ) ,
586+ recipe : Arc :: new ( MockRecipeResolver ) ,
587+ } ;
588+
589+ // Call load
590+ let result = loader. load ( ) . await ;
591+
592+ // Assert success and check project contents
593+ assert ! ( result. is_ok( ) ) ;
594+ let project = result. unwrap ( ) ;
595+ assert_eq ! ( project. dir, project_dir) ;
596+ assert ! (
597+ project. canisters. contains_key( "backend" ) ,
598+ "The backend canister was not found"
599+ ) ;
600+ assert ! (
601+ project. environments. contains_key( "local" ) ,
602+ "The default `local` environment was not injected"
603+ ) ;
604+ assert ! (
605+ project. environments. contains_key( "ic" ) ,
606+ "The default `ic` environment was not injected"
607+ ) ;
608+ assert ! (
609+ project. networks. contains_key( "local" ) ,
610+ "The default `local` network was not injected"
611+ ) ;
612+ assert ! (
613+ project. networks. contains_key( "ic" ) ,
614+ "The default `ic` network was not injected"
615+ ) ;
616+ }
617+
618+ #[ tokio:: test]
619+ async fn test_load_project_local_override ( ) {
620+ // Create temp directory with icp.yaml
621+ let temp_dir = Utf8TempDir :: new ( ) . unwrap ( ) ;
622+ let project_dir = temp_dir. path ( ) ;
623+
624+ // Write a minimal icp.yaml
625+ let manifest_content = indoc ! { r#"
626+ networks:
627+ - name: test-network
628+ mode: connected
629+ url: https://somenetwork.icp
630+ environments:
631+ - name: local
632+ network: test-network
633+ canisters:
634+ - name: backend
635+ build:
636+ steps:
637+ - type: pre-built
638+ path: backend.wasm
639+ "# } ;
640+ std:: fs:: write ( project_dir. join ( "icp.yaml" ) , manifest_content) . unwrap ( ) ;
641+
642+ // Create ProjectLoadImpl with mocks
643+ let loader = ProjectLoadImpl {
644+ project_root_locate : Arc :: new ( MockProjectRootLocate :: new ( project_dir. to_path_buf ( ) ) ) ,
645+ recipe : Arc :: new ( MockRecipeResolver ) ,
646+ } ;
647+
648+ // Call load
649+ let result = loader. load ( ) . await ;
650+
651+ // Assert success and check project contents
652+ assert ! ( result. is_ok( ) , "The project did not load: {:?}" , result) ;
653+ let project = result. unwrap ( ) ;
654+ assert_eq ! ( project. dir, project_dir) ;
655+ assert ! (
656+ project. canisters. contains_key( "backend" ) ,
657+ "The backend canister was not found"
658+ ) ;
659+ assert ! (
660+ project. environments. contains_key( "local" ) ,
661+ "The default `local` environment was not injected"
662+ ) ;
663+ let e = project. environments . get ( "local" ) . unwrap ( ) ;
664+ assert_eq ! ( e. network. name, "test-network" ) ;
665+ assert ! (
666+ project. environments. contains_key( "ic" ) ,
667+ "The default `ic` environment was not injected"
668+ ) ;
669+ assert ! (
670+ project. networks. contains_key( "local" ) ,
671+ "The default `local` network was not injected"
672+ ) ;
673+ assert ! (
674+ project. networks. contains_key( "ic" ) ,
675+ "The default `ic` network was not injected"
676+ ) ;
677+ }
678+ }
0 commit comments