More tests.

This commit is contained in:
Victor Zverovich 2014-05-03 13:14:15 -07:00
parent 9556d3714d
commit b808503bc1

View File

@ -27,6 +27,7 @@
#include "gtest-extra.h" #include "gtest-extra.h"
#include <cstring>
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
#include <gtest/gtest-spi.h> #include <gtest/gtest-spi.h>
@ -151,11 +152,14 @@ TEST(FileTest, DefaultCtor) {
} }
// Checks if the file is open by reading one character from it. // Checks if the file is open by reading one character from it.
// Note that IsOpen is not equivalent to !IsClosed.
bool IsOpen(int fd) { bool IsOpen(int fd) {
char buffer; char buffer;
return read(fd, &buffer, 1) == 1; return read(fd, &buffer, 1) == 1;
} }
// Checks if the file is closed.
// Note that IsClosed is not equivalent to !IsOpen.
bool IsClosed(int fd) { bool IsClosed(int fd) {
char buffer; char buffer;
std::streamsize result = read(fd, &buffer, 1); std::streamsize result = read(fd, &buffer, 1);
@ -251,19 +255,24 @@ TEST(FileTest, CloseError) {
FormatSystemErrorMessage(EBADF, "cannot close file") + "\n"); FormatSystemErrorMessage(EBADF, "cannot close file") + "\n");
} }
std::string ReadLine(File &f) { // Attempts to read count characters from the file.
enum { BUFFER_SIZE = 100 }; std::string Read(File &f, std::size_t count) {
char buffer[BUFFER_SIZE]; std::string buffer(count, '\0');
std::streamsize result = f.read(buffer, BUFFER_SIZE); std::streamsize offset = 0, n = 0;
buffer[std::min<std::streamsize>(BUFFER_SIZE - 1, result)] = '\0'; do {
if (char *end = strchr(buffer, '\n')) n = f.read(&buffer[offset], count - offset);
*end = '\0'; offset += n;
} while (offset < count && n != 0);
buffer.resize(offset);
return buffer; return buffer;
} }
#define EXPECT_READ(file, expected_content) \
EXPECT_EQ(expected_content, Read(f, std::strlen(expected_content)))
TEST(FileTest, Read) { TEST(FileTest, Read) {
File f(".travis.yml", File::RDONLY); File f(".travis.yml", File::RDONLY);
EXPECT_EQ("language: cpp", ReadLine(f)); EXPECT_READ(f, "language: cpp");
} }
TEST(FileTest, ReadError) { TEST(FileTest, ReadError) {
@ -272,11 +281,28 @@ TEST(FileTest, ReadError) {
EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file"); EXPECT_SYSTEM_ERROR(f.read(&buf, 1), EBADF, "cannot read from file");
} }
TEST(FileTest, Write) {
// TODO: use pipes
const char EXPECTED[] = "test";
{
File f("out", File::WRONLY);
enum { SIZE = sizeof(EXPECTED) - 1 };
std::streamsize offset = 0, count = 0;
do {
count = f.write(EXPECTED + offset, SIZE - offset);
offset += count;
} while (offset < SIZE && count != 0);
}
File f("out", File::RDONLY);
EXPECT_READ(f, EXPECTED);
}
TEST(FileTest, Dup) { TEST(FileTest, Dup) {
File f(".travis.yml", File::RDONLY); File f(".travis.yml", File::RDONLY);
File dup = File::dup(f.get()); File dup = File::dup(f.get());
EXPECT_NE(f.get(), dup.get()); EXPECT_NE(f.get(), dup.get());
EXPECT_EQ("language: cpp", ReadLine(dup)); const char EXPECTED[] = "language: cpp";
EXPECT_EQ(EXPECTED, Read(dup, sizeof(EXPECTED) - 1));
} }
TEST(FileTest, DupError) { TEST(FileTest, DupError) {
@ -289,14 +315,13 @@ TEST(FileTest, Dup2) {
File dup("CMakeLists.txt", File::RDONLY); File dup("CMakeLists.txt", File::RDONLY);
f.dup2(dup.get()); f.dup2(dup.get());
EXPECT_NE(f.get(), dup.get()); EXPECT_NE(f.get(), dup.get());
EXPECT_EQ("language: cpp", ReadLine(dup)); EXPECT_READ(dup, "language: cpp");
} }
TEST(FileTest, Dup2Error) { TEST(FileTest, Dup2Error) {
File f(".travis.yml", File::RDONLY); File f(".travis.yml", File::RDONLY);
EXPECT_SYSTEM_ERROR(f.dup2(-1), EBADF, EXPECT_SYSTEM_ERROR(f.dup2(-1), EBADF,
fmt::Format("cannot duplicate file descriptor {} to -1") << f.get()); fmt::Format("cannot duplicate file descriptor {} to -1") << f.get());
} }
TEST(FileTest, Dup2NoExcept) { TEST(FileTest, Dup2NoExcept) {
@ -306,7 +331,7 @@ TEST(FileTest, Dup2NoExcept) {
f.dup2(dup.get(), ec); f.dup2(dup.get(), ec);
EXPECT_EQ(0, ec.get()); EXPECT_EQ(0, ec.get());
EXPECT_NE(f.get(), dup.get()); EXPECT_NE(f.get(), dup.get());
EXPECT_EQ("language: cpp", ReadLine(dup)); EXPECT_READ(dup, "language: cpp");
} }
TEST(FileTest, Dup2NoExceptError) { TEST(FileTest, Dup2NoExceptError) {