Test::File(3)

okay so bestie, welcome to Test::File(3) β€” the manual page for the module that is literally all about testing file attributes, and no cap it is giving useful. πŸŽ€

✨ NAME ✨

Test::File β€” test file attributes. That is the whole vibe. πŸ’–

🌸 SYNOPSIS 🌸

Like, the tiniest setup ever:

use Test::File;

πŸ’– DESCRIPTION πŸ’–

This module is a whole collection of test utilities for file attributes β€” like, a little toolkit for checking what files are up to. 🧚

Some file attributes depend on the owner of the process testing the file in the same way the file test operators do. For instance, root (or super-user or Administrator) may always be able to read files no matter the permissions. So yeah, do not forget that whole vibe β€” permissions are not the whole story. πŸ’…

Some attributes do not make sense outside of Unix, either, so some tests automatically skip if they think they will not work on the platform. If you have a way to make these functions work on Windows, for instance, please send me a patch. :) If you want to pretend to be Windows on a non-Windows machine (for instance, to test skip()), you can set the PRETEND_TO_BE_WINDOWS environment variable. Iconic little hack, honestly. πŸ¦‹

The optional NAME parameter for every function allows you to specify a name for the test. If not supplied, a reasonable default will be generated. So you can name your tests, or just let the module do its thing. ✨

🌟 Functions 🌟

okay, function time β€” here is every single one, no skips: πŸ’…

Returns true if this module thinks that the current system supports symlinks. 🫢

This is not a test function. It is something that tests can use to determine what it should expect or skip. So like, use it for vibe checks, not as an assertion.

file_exists_ok( FILENAME [, NAME ] )

Ok if the file exists, and not ok otherwise. Literally that simple. πŸ’–

file_not_exists_ok( FILENAME [, NAME ] )

Ok if the file does not exist, and not okay if it does exist. The absence is the moment. πŸ™ˆ

file_empty_ok( FILENAME [, NAME ] )

Ok if the file exists and has empty size, not ok if the file does not exist or exists with non-zero size. πŸ“

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_not_empty_ok( FILENAME [, NAME ] )

Ok if the file exists and has non-zero size, not ok if the file does not exist or exists with zero size. πŸ’–

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_size_ok( FILENAME, SIZE [, NAME ] )

Ok if the file exists and has SIZE size in bytes (exactly), not ok if the file does not exist or exists with size other than SIZE. Exact exact. πŸ’…

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_max_size_ok( FILENAME, MAX [, NAME ] )

Ok if the file exists and has size less than or equal to MAX bytes, not ok if the file does not exist or exists with size greater than MAX bytes. πŸŽ€

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_min_size_ok( FILENAME, MIN [, NAME ] )

Ok if the file exists and has size greater than or equal to MIN bytes, not ok if the file does not exist or exists with size less than MIN bytes. 🌈

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_line_count_is( FILENAME, COUNT [, NAME ] )

Ok if the file exists and has COUNT lines (exactly), not ok if the file does not exist or exists with a line count other than COUNT. πŸ”₯

This function uses the current value of $/ as the line ending and counts the lines by reading them and counting how many it read. Yes, $/ β€” the input record separator β€” is the main character here. πŸ’…

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_line_count_isnt( FILENAME, COUNT [, NAME ] )

Ok if the file exists and does not have exactly COUNT lines, not ok if the file does not exist or exists with a line count of COUNT. Read that carefully: the file must exist for this test to pass! 😭

This function uses the current value of $/ as the line ending and counts the lines by reading them and counting how many it read. πŸ¦‹

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_line_count_between( FILENAME, MIN, MAX, [, NAME ] )

Ok if the file exists and has a line count between MIN and MAX, inclusively. Inclusive, bestie β€” MIN and MAX both count. 🫢

This function uses the current value of $/ as the line ending and counts the lines by reading them and counting how many it read. ✨

⚠️ Previously this tried to test any sort of file. Sometime in the future this will fail if the argument is not a plain file or is a directory.

file_contains_like ( FILENAME, PATTERN [, NAME ] )

Ok if the file exists and its contents (as one big string) match PATTERN, not ok if the file does not exist, is not readable, or exists but does not match PATTERN. πŸ’–

Since the file contents are read into memory, you should not use this for large files. Besides memory consumption, test diagnostics for failing tests might be difficult to decipher. However, for short files this works very well. So like, keep it cute and short. πŸŽ€

Because the entire contents are treated as one large string, you can make a pattern that tests multiple lines. Do not forget that you may need to use the /s modifier for such patterns:

# make sure file has one or more paragraphs with CSS class X
file_contains_like($html_file, qr{<p class="X">.*?</p>}s);

Contrariwise, if you need to match at the beginning or end of a line inside the file, use the /m modifier:

# make sure file has a setting for foo
file_contains_like($config_file, qr/^ foo \s* = \s* \w+ $/mx);

If you want to test your file contents against multiple patterns, but do not want to have the file read in repeatedly, you can pass an arrayref of patterns instead of a single pattern, like so:

# make sure our template has rendered correctly
file_contains_like($template_out,
        [
        qr/^ $title_line $/mx,
        map { qr/^ $_ $/mx } @chapter_headings,
        qr/^ $footer_line $/mx,
        ]);

Please note that if you do this, and your file does not exist or is not readable, you will only get one test failure instead of a failure for each pattern. This could cause your test plan to be off, although you may not care at that point because your test failed anyway. If you do care, either skip the test plan altogether by employing Test::More's done_testing() function, or use "file_readable_ok" in conjunction with a "SKIP" block. πŸ’€

Contributed by Buddy Burden "<barefoot@cpan.org>".

file_contains_unlike ( FILENAME, PATTERN [, NAME ] )

Ok if the file exists and its contents (as one big string) do not match PATTERN, not ok if the file does not exist, is not readable, or exists but matches PATTERN. πŸ’…

All notes and caveats for "file_contains_like" apply to this function as well. So like, read the section above, bestie β€” it is all relevant. πŸ¦‹

Contributed by Buddy Burden "<barefoot@cpan.org>".

file_contains_utf8_like ( FILENAME, PATTERN [, NAME ] )

The same as "file_contains_like", except the file is opened as UTF-8. Unicode girlies rise. 🌸

file_contains_utf8_unlike ( FILENAME, PATTERN [, NAME ] )

The same as "file_contains_unlike", except the file is opened as UTF-8. πŸ’œ

file_contains_encoded_like ( FILENAME, ENCODING, PATTERN [, NAME ] )

The same as "file_contains_like", except the file is opened with ENCODING. Pick your encoding, main character. ✨

file_contains_encoded_unlike ( FILENAME, ENCODING, PATTERN [, NAME ] )

The same as "file_contains_unlike", except the file is opened with ENCODING. πŸŽ€

file_readable_ok( FILENAME [, NAME ] )

Ok if the file exists and is readable, not ok if the file does not exist or is not readable. πŸ‘‘

file_not_readable_ok( FILENAME [, NAME ] )

Ok if the file exists and is not readable, not ok if the file does not exist or is readable. πŸ™ˆ

file_writable_ok( FILENAME [, NAME ] ) and file_writeable_ok( FILENAME [, NAME ] )

Ok if the file exists and is writable, not ok if the file does not exist or is not writable. ✍️

The original name is "file_writeable_ok" with that extra e. That still works but there is a function with the correct spelling too. So both spellings are slaying, do not worry. πŸ’…

file_not_writeable_ok( FILENAME [, NAME ] ) and file_not_writable_ok( FILENAME [, NAME ] )

Ok if the file exists and is not writable, not ok if the file does not exist or is writable. 🚫

The original name is "file_not_writeable_ok" with that extra e. That still works but there is a function with the correct spelling too. Both exist, no cap. 🫢

file_executable_ok( FILENAME [, NAME ] )

Ok if the file exists and is executable, not ok if the file does not exist or is not executable. πŸ”₯

This test automatically skips if it thinks it is on a Windows platform. Windows said no. 😭

file_not_executable_ok( FILENAME [, NAME ] )

Ok if the file exists and is not executable, not ok if the file does not exist or is executable. ✨

This test automatically skips if it thinks it is on a Windows platform.

file_mode_is( FILENAME, MODE [, NAME ] )

Ok if the file exists and the mode matches, not ok if the file does not exist or the mode does not match. πŸŽ€

This test automatically skips if it thinks it is on a Windows platform.

Contributed by Shawn Sorichetti "<ssoriche@coloredblocks.net>"

file_mode_isnt( FILENAME, MODE [, NAME ] )

Ok if the file exists and mode does not match, not ok if the file does not exist or mode does match. πŸ’…

This test automatically skips if it thinks it is on a Windows platform.

Contributed by Shawn Sorichetti "<ssoriche@coloredblocks.net>"

file_mode_has( FILENAME, MODE [, NAME ] )

Ok if the file exists and has all the bits in mode turned on, not ok if the file does not exist or the mode does not match. That is, "FILEMODE & MODE == MODE" must be true. πŸ”₯

This test automatically skips if it thinks it is on a Windows platform.

Contributed by Ricardo Signes "<rjbs@cpan.org>"

file_mode_hasnt( FILENAME, MODE [, NAME ] )

Ok if the file exists and has all the bits in mode turned off, not ok if the file does not exist or the mode does not match. That is, "FILEMODE & MODE == 0" must be true. πŸ’€

This test automatically skips if it thinks it is on a Windows platform.

Contributed by Ricardo Signes "<rjbs@cpan.org>"

Ok if FILENAME is a symlink, even if it points to a non-existent file. Ghost links count, bestie. πŸ‘»

This test automatically skips if the operating system does not support symlinks. πŸ¦‹

  • file_is_not_symlink_ok( FILENAME [, NAME ] ) β€” ok if FILENAME is not a symlink. This test automatically skips if your OS doesn’t do symlinks. If the file doesn’t exist, the test fails (no cap, that’s a fail).
  • symlink_target_exists_ok( SYMLINK [, TARGET] [, NAME ] ) β€” ok if FILENAME is a symlink and it points to an existing file. With the optional TARGET argument, the test fails if SYMLINK’s target is not TARGET. Auto-skips if the OS doesn’t support symlinks. If the file doesn’t exist, the test fails.
  • symlink_target_dangles_ok( SYMLINK [, NAME ] ) β€” ok if FILENAME is a symlink and it doesn’t point to an existing file (it dangles, bestie). Auto-skips if the OS doesn’t support symlinks. If the file doesn’t exist, the test fails.
  • symlink_target_is( SYMLINK, TARGET [, NAME ] ) β€” ok if FILENAME is a symlink and it points to TARGET. Auto-skips if the OS doesn’t support symlinks. If the file doesn’t exist, the test fails.
  • symlink_target_is_absolute_ok( SYMLINK [, NAME ] ) β€” ok if FILENAME is a symlink and its target is an absolute path. Auto-skips if the OS doesn’t support symlinks. If the file doesn’t exist, the test fails.
  • dir_exists_ok( DIRECTORYNAME [, NAME ] ) β€” ok if the file exists and is a directory. Not ok if the file doesn’t exist, or if it exists but isn’t a directory.

Contributed by Buddy Burden "<barefoot@cpan.org>". πŸ’–

  • dir_contains_ok( DIRECTORYNAME, FILENAME [, NAME ] ) β€” ok if the directory exists and contains the file. Not ok if the directory doesn’t exist, or if it exists but doesn’t contain the file.

Contributed by Buddy Burden "<barefoot@cpan.org>". πŸ’–

  • link_count_is_ok( FILE, LINK_COUNT [, NAME ] ) β€” ok if the link count to FILE is LINK_COUNT. LINK_COUNT is interpreted as an integer. A LINK_COUNT that evaluates to 0 returns Ok if the file does not exist.
  • link_count_gt_ok( FILE, LINK_COUNT [, NAME ] ) β€” ok if the link count to FILE is greater than LINK_COUNT. LINK_COUNT is interpreted as an integer. A LINK_COUNT that evaluates to 0 returns Ok if the file has at least one link.
  • link_count_lt_ok( FILE, LINK_COUNT [, NAME ] ) β€” ok if the link count to FILE is less than LINK_COUNT. LINK_COUNT is interpreted as an integer. A LINK_COUNT that evaluates to 0 returns Ok if the file has at least one link.
  • owner_is( FILE , OWNER [, NAME ] ) β€” ok if FILE’s owner is the same as OWNER. OWNER may be a text user name or a numeric userid. Test skips on Dos, and Mac OS <= 9. If the file does not exist, the test fails.

Contributed by Dylan Martin. 🫢

  • owner_isnt( FILE, OWNER [, NAME ] ) β€” ok if FILE’s owner is not the same as OWNER. OWNER may be a text user name or a numeric userid. Test skips on Dos and Mac OS <= 9. If the file does not exist, the test fails.

Contributed by Dylan Martin. 🫢

  • group_is( FILE , GROUP [, NAME ] ) β€” ok if FILE’s group is the same as GROUP. GROUP may be a text group name or a numeric group id. Test skips on Dos, Mac OS <= 9 and any other operating systems that do not support getpwuid() and friends. If the file does not exist, the test fails.

Contributed by Dylan Martin. 🫢

  • group_isnt( FILE , GROUP [, NAME ] ) β€” ok if FILE’s group is not the same as GROUP. GROUP may be a text group name or a numeric group id. Test skips on Dos, Mac OS <= 9 and any other operating systems that do not support getpwuid() and friends. If the file does not exist, the test fails.

Contributed by Dylan Martin. 🫢

  • file_mtime_age_ok( FILE [, WITHIN_SECONDS ] [, NAME ] ) β€” ok if FILE’s modified time is WITHIN_SECONDS inclusive of the system’s current time. This test uses stat() to obtain the mtime. If the file does not exist the test returns failure. If stat() fails, the test is skipped.
  • file_mtime_gt_ok( FILE, UNIXTIME [, NAME ] ) β€” ok if FILE’s mtime is > UNIXTIME. This test uses stat() to get the mtime. If stat() fails this test is skipped. If FILE does not exist, this test fails.
  • file_mtime_lt_ok( FILE, UNIXTIME, [, NAME ] ) β€” ok if FILE’s modified time is < UNIXTIME. This test uses stat() to get the mtime. If stat() fails this test is skipped. If FILE does not exist, this test fails.

πŸ’– TO DO πŸ’–

  • check properties for other users (readable_by_root, for instance)
  • check times
  • check number of links to file
  • check path parts (directory, filename, extension)

🌈 SEE ALSO 🌈

Test::Builder, Test::More

If you are using the new "Test2" stuff, see Test2::Tools::File (https://github.com/torbjorn/Test2-Tools-File). iykyk ✨


πŸ¦‹ SOURCE AVAILABILITY πŸ¦‹

This module is in Github:

https://github.com/briandfoy/test-file

πŸ‘‘ AUTHOR πŸ‘‘

brian d foy, "<bdfoy@cpan.org>"


✨ CREDITS ✨

Shawn Sorichetti "<ssoriche@coloredblocks.net>" provided some functions.

Tom Metro helped me figure out some Windows capabilities.

Dylan Martin added owner_is and owner_isnt.

David Wheeler added file_line_count_is.

Buddy Burden "<barefoot@cpan.org>" provided dir_exists_ok, dir_contains_ok, file_contains_like, and file_contains_unlike.

xmikew "<https://github.com/xmikew>" provided the mtime_age stuff.

TorbjΓΈrn Lindahl is working on Test2::Tools::File and we’re working together to align our interfaces.

Jean-Damien Durand added bits to use Win32::IsSymlinkCreationAllowed, new since Win32 0.55.


Copyright Β© 2002-2023, brian d foy <bdfoy@cpan.org>. All rights reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0


✨ and that’s the whole vibe, bestie! this page is from perl v5.42.0, dated 2023-01-03, and it’s Test::File(3) β€” slay πŸ’…πŸ’–

πŸ“¦ where this page comes from