describe("file_info", { with_dir_tree(list( "foo/bar" = "test", "NA" = ""), { link_create(path_abs("foo"), "foo2") it("returns a correct tibble", { x <- file_info(c("foo", "foo/bar", "foo2", "NA")) expect_s3_class(x, c("tbl", "tbl_df", "data.frame")) expect_length(x, 18) expect_equal(nrow(x), 4) expect_equal(as.character(x$path), c("foo", "foo/bar", "foo2", "NA")) expect_equal(as.character(x$type), c("directory", "file", "symlink", "file")) }) it("returns NA if a file does not exist", { x <- file_info("missing") expect_s3_class(x, c("tbl", "tbl_df", "data.frame")) expect_length(x, 18) expect_equal(nrow(x), 1) expect_equal(as.character(x$path), "missing") expect_equal(sum(is.na(x)), 17) }) it("returns NA on NA input", { x <- file_info(NA_character_) expect_s3_class(x, c("tbl", "tbl_df", "data.frame")) expect_length(x, 18) expect_equal(nrow(x), 1) expect_equal(as.character(x$path), NA_character_) expect_equal(sum(is.na(x)), 18) }) it("can be subset as a data.frame", { x <- file_info("foo/bar") class(x) <- "data.frame" for (col in seq_along(x)) { expect_true(length(x[[1, col]]) == 1) } }) it("can be subset as a tibble", { x <- file_info("foo/bar") expect_s3_class(x, "tbl_df") for (col in seq_along(x)) { expect_true(length(x[[1, col]]) == 1) } }) }) }) describe("file_size", { with_dir_tree(list( "foo" = "test", "bar" = "test2"), { it("returns the correct file size", { expect_equal(file_size("foo"), stats::setNames(file_info("foo")$size, "foo")) expect_equal(file_size("bar"), stats::setNames(file_info("bar")$size, "bar")) }) it("returns an object of class fs_bytes, numeric (#239)", { expect_equal(class(file_size("foo")), c("fs_bytes", "numeric")) expect_equal(class(file_size("foo")[]), c("fs_bytes", "numeric")) }) }) }) # Windows permissions only really allow setting read only, so we will skip # the more thorough tests if (!is_windows()) { describe("file_chmod", { with_dir_tree(list("foo/bar" = "test"), { it("returns the input path and changes permissions with symbolic input", { expect_equal(file_chmod("foo/bar", "u=rw,go=r"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("644")) ) expect_equal(file_chmod("foo/bar", "u+x"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("744")) ) expect_equal(file_chmod("foo/bar", "g-r"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("704")) ) expect_equal(file_chmod("foo/bar", "o-r"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("700")) ) }) it("returns the input path and changes permissions with octal input", { expect_equal(file_chmod("foo/bar", "644"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("644")) ) expect_equal(file_chmod("foo/bar", "744"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("744")) ) expect_equal(file_chmod("foo/bar", "704"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("704")) ) expect_equal(file_chmod("foo/bar", "700"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("700")) ) }) it("returns the input path and changes permissions with display input", { expect_equal(file_chmod("foo/bar", "rw-r--r--"), fs_path("foo/bar")) expect_true(file_info("foo/bar")$permissions == "644") expect_equal(file_chmod("foo/bar", "rwxr--r--"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("744")) ) expect_equal(file_chmod("foo/bar", "rwx---r--"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("704")) ) expect_equal(file_chmod("foo/bar", "rwx------"), fs_path("foo/bar")) expect_equal( as.character(file_info("foo/bar")$permissions), as.character(fs_perms("700")) ) }) it("errors if given an invalid mode", { expect_error(file_chmod("foo", "g+S"), "Invalid mode 'g\\+S'") }) it("errors on missing input", { expect_error(file_chmod(NA, "u+x"), class = "invalid_argument") }) it("is vectorized over files and permissions", { file_create("foo/baz") files <- c("foo/bar", "foo/baz") expect_equal(file_chmod(files, "000"), fs_path(files)) expect_true(all(file_info(files)$permissions == c("000", "000"))) expect_equal(file_chmod(files, "644"), fs_path(files)) expect_true(all(file_info(files)$permissions == c("644", "644"))) expect_equal(file_chmod(files, c("u+x", "o+x")), fs_path(files)) expect_true(all(file_info(files)$permissions == c("744", "645"))) expect_error(file_chmod(files, c("u+x", "o+x", "g+x")), class = "invalid_argument") }) }) }) } describe("file_chown", { with_dir_tree(list("foo/bar" = "test"), { it("changes the ownership of a file, returns the input path", { skip("need elevated permissions to change uid") # Make everyone have write access, so we can delete this after changing ownership file_chmod("foo/bar", "a+w") # Change ownership to root expect_equal(file_chown("foo/bar", user_id = 0), "foo/bar") expect_true(file_info("foo/bar")$user == "root") }) it("errors on missing input", { expect_error(file_chown(NA, user_id = 0), class = "invalid_argument") }) }) }) describe("file_move", { it("renames files in the same directory", { with_dir_tree(list("foo" = "test"), { expect_true(file_exists("foo")) expect_equal(file_move("foo", "bar"), fs_path("bar")) expect_false(file_exists("foo")) expect_true(file_exists("bar")) }) }) it("renames files in different directories", { with_dir_tree(list("foo/bar" = "test", "foo2"), { expect_true(file_exists("foo/bar")) expect_true(file_exists("foo2")) expect_equal(file_move("foo/bar", "foo2"), fs_path("foo2/bar")) expect_false(file_exists("foo/bar")) expect_true(file_exists("foo2/bar")) expect_error(file_move("foo/bar", c("foo2", "foo3")), class = "fs_error") }) }) it("errors on missing input", { expect_error(file_move(NA, "foo2"), class = "invalid_argument") expect_error(file_move("foo", NA), class = "invalid_argument") }) }) describe("file_touch", { it("updates modification_time and access_time", { with_dir_tree("dir", { file_create("foo") now <- Sys.time() file_touch("foo", now) old <- file_info("foo") file_touch("foo", now + 10, now + 20) new <- file_info("foo") expect_true(old$modification_time < new$modification_time) expect_true(old$access_time < new$access_time) file_touch("foo", now - 10, now - 20) new2 <- file_info("foo") expect_true(old$modification_time > new2$modification_time) expect_true(old$access_time > new2$access_time) }) }) it("errors on missing input", { expect_error(file_touch(NA), class = "invalid_argument") }) it("creates the file if it doesn't exist", { with_dir_tree("dir", { file_touch("foo") expect_true(file_exists("foo")) }) }) })