fn smoke_create_and_apply()

in focus/util/src/git/snapshot.rs [231:315]


    fn smoke_create_and_apply() -> Result<()> {
        init_logging();

        let app = Arc::new(App::new_for_testing()?);
        let repo_dir = app.sandbox().create_subdirectory("repo")?;

        let repo = ScratchGitRepo::new_static_fixture(&repo_dir)?;

        let tracked_removed_filename = PathBuf::from("a-tracked-file-added-and-later-deleted.txt");
        let tracked_removed_path = repo.path().join(&tracked_removed_filename);
        let tracked_removed_content = b"This file is added and later deleted.\n";
        std::fs::write(&tracked_removed_path, tracked_removed_content)?;
        repo.add_file(&tracked_removed_filename)?;
        repo.write_and_commit_file(
            &tracked_removed_filename,
            tracked_removed_content,
            format!("Commit of {}", tracked_removed_filename.display()),
        )?;
        repo.remove_file(&tracked_removed_filename)?;

        let tracked_filename = PathBuf::from("a-tracked-file.txt");
        let tracked_file_path = repo.path().join(&tracked_filename);
        let tracked_file_content = b"This file is added.\n";
        std::fs::write(&tracked_file_path, tracked_file_content)?;
        repo.add_file(&tracked_filename)?;

        let untracked_file_name = PathBuf::from("an-untracked-file.txt");
        let untracked_file_path = repo.path().join(&untracked_file_name);
        let untracked_content = b"This file is untracked.\n";
        std::fs::write(&untracked_file_path, untracked_content)?;

        // Check that the status is what we expect.
        let initial_status = git::working_tree::status(repo.path(), app.clone())?;
        {
            let untracked_entries =
                initial_status.find_entries_with_disposition(Disposition::Untracked)?;
            let untracked_entry = untracked_entries
                .first()
                .ok_or_else(|| anyhow::anyhow!("Expected an untracked entry and there was none"))?;
            assert_eq!(untracked_entry.path.as_path(), &untracked_file_name);

            let tracked_entries =
                initial_status.find_entries_with_disposition(Disposition::Added)?;
            {
                let tracked_entry = tracked_entries.first().ok_or_else(|| {
                    anyhow::anyhow!("Expected an untracked entry and there was none")
                })?;
                assert_eq!(tracked_entry.path.as_path(), &tracked_filename);
            }
        }

        let snapshot = git::snapshot::create(repo.path(), app.clone())
            .context("Creating the snapshot failed")?
            .ok_or_else(|| anyhow::anyhow!("Expected a snapshot to be created"))?;
        let snapshot_stat =
            std::fs::metadata(snapshot.as_path()).context("Could not stat snapshot file")?;
        assert!(snapshot_stat.is_file());
        assert!(snapshot_stat.len() > 0);

        // After the snapshot is created, the tree should be in a clean state.
        {
            let status = git::working_tree::status(repo.path(), app.clone())?;
            tracing::debug!(entries = ?status.entries());
            assert!(status.is_empty());
        }

        // Apply the snapshot, check that everything is as before.
        {
            assert!(tracked_removed_path.is_file());

            git::snapshot::apply(snapshot.as_path(), repo.path(), true, app.clone())
                .context("Applying snapshot failed")?;

            // The patch should have removed the file.
            assert!(!tracked_removed_path.is_file());

            // The working tree status should be the same.
            let status = git::working_tree::status(repo.path(), app.clone())?;
            assert_eq!(status, initial_status);
        }

        drop(app);

        Ok(())
    }