Add a test

Kirill Bulatov created

Change summary

crates/project/src/worktree_tests.rs | 139 +++++++++++++++++++++++++++++
1 file changed, 139 insertions(+)

Detailed changes

crates/project/src/worktree_tests.rs 🔗

@@ -990,6 +990,145 @@ async fn test_file_scan_exclusions(cx: &mut TestAppContext) {
     });
 }
 
+#[gpui::test]
+async fn test_fs_events_in_exclusions(cx: &mut TestAppContext) {
+    init_test(cx);
+    let dir = temp_tree(json!({
+        ".git": {
+            "HEAD": "ref: refs/heads/main\n",
+            "foo": "bar",
+        },
+        ".gitignore": "**/target\n/node_modules\ntest_output\n",
+        "target": {
+            "index": "blah2"
+        },
+        "node_modules": {
+            ".DS_Store": "",
+            "prettier": {
+                "package.json": "{}",
+            },
+        },
+        "src": {
+            ".DS_Store": "",
+            "foo": {
+                "foo.rs": "mod another;\n",
+                "another.rs": "// another",
+            },
+            "bar": {
+                "bar.rs": "// bar",
+            },
+            "lib.rs": "mod foo;\nmod bar;\n",
+        },
+        ".DS_Store": "",
+    }));
+    cx.update(|cx| {
+        cx.update_global::<SettingsStore, _, _>(|store, cx| {
+            store.update_user_settings::<ProjectSettings>(cx, |project_settings| {
+                project_settings.file_scan_exclusions = Some(vec![
+                    "**/.git".to_string(),
+                    "node_modules/".to_string(),
+                    "build_output".to_string(),
+                ]);
+            });
+        });
+    });
+
+    let tree = Worktree::local(
+        build_client(cx),
+        dir.path(),
+        true,
+        Arc::new(RealFs),
+        Default::default(),
+        &mut cx.to_async(),
+    )
+    .await
+    .unwrap();
+    cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete())
+        .await;
+    tree.flush_fs_events(cx).await;
+    tree.read_with(cx, |tree, _| {
+        check_worktree_entries(
+            tree,
+            &[
+                ".git/HEAD",
+                ".git/foo",
+                "node_modules/.DS_Store",
+                "node_modules/prettier",
+                "node_modules/prettier/package.json",
+            ],
+            &["target", "node_modules"],
+            &[
+                ".DS_Store",
+                "src/.DS_Store",
+                "src/lib.rs",
+                "src/foo/foo.rs",
+                "src/foo/another.rs",
+                "src/bar/bar.rs",
+                ".gitignore",
+            ],
+        )
+    });
+
+    let new_excluded_dir = dir.path().join("build_output");
+    let new_ignored_dir = dir.path().join("test_output");
+    std::fs::create_dir_all(&new_excluded_dir)
+        .unwrap_or_else(|e| panic!("Failed to create a {new_excluded_dir:?} directory: {e}"));
+    std::fs::create_dir_all(&new_ignored_dir)
+        .unwrap_or_else(|e| panic!("Failed to create a {new_ignored_dir:?} directory: {e}"));
+    let node_modules_dir = dir.path().join("node_modules");
+    let dot_git_dir = dir.path().join(".git");
+    let src_dir = dir.path().join("src");
+    for existing_dir in [&node_modules_dir, &dot_git_dir, &src_dir] {
+        assert!(
+            existing_dir.is_dir(),
+            "Expect {existing_dir:?} to be present in the FS already"
+        );
+    }
+
+    for directory_for_new_file in [
+        new_excluded_dir,
+        new_ignored_dir,
+        node_modules_dir,
+        dot_git_dir,
+        src_dir,
+    ] {
+        std::fs::write(directory_for_new_file.join("new_file"), "new file contents")
+            .unwrap_or_else(|e| {
+                panic!("Failed to create in {directory_for_new_file:?} a new file: {e}")
+            });
+    }
+    tree.flush_fs_events(cx).await;
+
+    tree.read_with(cx, |tree, _| {
+        check_worktree_entries(
+            tree,
+            &[
+                ".git/HEAD",
+                ".git/foo",
+                ".git/new_file",
+                "node_modules/.DS_Store",
+                "node_modules/prettier",
+                "node_modules/prettier/package.json",
+                "node_modules/new_file",
+                "build_output",
+                "build_output/new_file",
+                "test_output/new_file",
+            ],
+            &["target", "node_modules", "test_output"],
+            &[
+                ".DS_Store",
+                "src/.DS_Store",
+                "src/lib.rs",
+                "src/foo/foo.rs",
+                "src/foo/another.rs",
+                "src/bar/bar.rs",
+                "src/new_file",
+                ".gitignore",
+            ],
+        )
+    });
+}
+
 #[gpui::test(iterations = 30)]
 async fn test_create_directory_during_initial_scan(cx: &mut TestAppContext) {
     init_test(cx);