Skip to content

Commit f8863c8

Browse files
Aditya Shastrifacebook-github-bot
authored andcommitted
Implement LocalFileWriter with tests (#91)
Summary: Pull Request resolved: #91 See title, implementation is fairly simple Reviewed By: elliottlawrence Differential Revision: D34885840 fbshipit-source-id: 6f118dc96bd392f8aaf563520c2ed7e7ae776b7a
1 parent f46b5d2 commit f8863c8

5 files changed

Lines changed: 117 additions & 4 deletions

File tree

fbpcf/io/api/LocalFileWriter.cpp

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,30 @@
77

88
#include "fbpcf/io/api/LocalFileWriter.h"
99
#include <cstddef>
10+
#include <stdexcept>
1011
#include <string>
1112
#include <vector>
1213

1314
namespace fbpcf::io {
14-
LocalFileWriter::LocalFileWriter(std::string /* filePath */) {}
15+
LocalFileWriter::LocalFileWriter(std::string filePath) {
16+
outputStream_ = std::make_unique<std::ofstream>(filePath);
17+
}
1518

1619
int LocalFileWriter::close() {
17-
return 0;
20+
outputStream_->close();
21+
22+
return outputStream_->fail() ? -1 : 0;
1823
}
19-
size_t LocalFileWriter::write(std::vector<char>& /* buf */) {
20-
return 0;
24+
25+
size_t LocalFileWriter::write(std::vector<char>& buf) {
26+
outputStream_->write(buf.data(), buf.size());
27+
28+
if (outputStream_->fail()) {
29+
throw std::runtime_error(
30+
"Internal error when writing to local file. Stream integrity may have been affected.");
31+
}
32+
33+
return buf.size();
2134
}
2235

2336
LocalFileWriter::~LocalFileWriter() {

fbpcf/io/api/LocalFileWriter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#pragma once
99
#include <cstddef>
10+
#include <fstream>
11+
#include <memory>
1012
#include <string>
1113
#include <vector>
1214

@@ -26,6 +28,9 @@ class LocalFileWriter : public IWriterCloser {
2628
int close() override;
2729
size_t write(std::vector<char>& buf) override;
2830
~LocalFileWriter() override;
31+
32+
private:
33+
std::unique_ptr<std::ofstream> outputStream_;
2934
};
3035

3136
} // namespace fbpcf::io
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#include <gtest/gtest.h>
9+
#include <stdio.h>
10+
#include <filesystem>
11+
#include <string>
12+
#include "folly/logging/xlog.h"
13+
14+
#include "fbpcf/io/api/LocalFileWriter.h"
15+
#include "fbpcf/io/api/test/utils/IOTestHelper.h"
16+
17+
namespace fbpcf::io {
18+
19+
inline void cleanup(std::string fileToDelete) {
20+
remove(fileToDelete.c_str());
21+
}
22+
23+
TEST(LocalFileWriterTest, testWritingToFile) {
24+
std::string baseDir = IOTestHelper::getBaseDirFromPath(__FILE__);
25+
std::string fileToWriteTo = baseDir + "data/local_file_writer_test_file.txt";
26+
auto writer = std::make_unique<fbpcf::io::LocalFileWriter>(fileToWriteTo);
27+
28+
/*
29+
CASE 1
30+
Write simple string to file
31+
*/
32+
std::string toWrite =
33+
"this file contains the expected text in local_file_writer_test_file.text";
34+
auto buf =
35+
std::vector<char>(toWrite.c_str(), toWrite.c_str() + toWrite.size());
36+
auto nBytes = writer->write(buf);
37+
EXPECT_EQ(nBytes, toWrite.size());
38+
39+
/*
40+
CASE 2
41+
Write arbitrary bytes to file
42+
*/
43+
std::vector<char> arbitraryBytes{'\n', '\n', 'L', 'o', 'c', 'a', 'l', 'F',
44+
'i', 'l', 'e', 'W', 'r', 'i', 't', 'e',
45+
'r', 'T', 'e', 's', 't', ' '};
46+
nBytes = writer->write(arbitraryBytes);
47+
EXPECT_EQ(nBytes, arbitraryBytes.size());
48+
49+
/*
50+
CASE 3
51+
Write larger buffer
52+
*/
53+
std::string remainingLine =
54+
"writes to the above file\nWe assert that it's contents match this file\n";
55+
auto buf2 = std::vector<char>(
56+
remainingLine.c_str(), remainingLine.c_str() + remainingLine.size());
57+
nBytes = writer->write(buf2);
58+
EXPECT_EQ(nBytes, remainingLine.size());
59+
60+
EXPECT_EQ(writer->close(), 0);
61+
62+
/*
63+
Verify that file contents match the expected
64+
*/
65+
IOTestHelper::expectFileContentsMatch(
66+
fileToWriteTo, baseDir + "data/expected_local_file_writer_test_file.txt");
67+
68+
cleanup(fileToWriteTo);
69+
}
70+
71+
} // namespace fbpcf::io
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
this file contains the expected text in local_file_writer_test_file.text
2+
3+
LocalFileWriterTest writes to the above file
4+
We assert that it's contents match this file

fbpcf/io/api/test/utils/IOTestHelper.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#pragma once
99

1010
#include <gtest/gtest.h>
11+
#include <fstream>
12+
#include <memory>
13+
1114
#include <string>
1215

1316
namespace fbpcf::io {
@@ -26,6 +29,23 @@ class IOTestHelper {
2629
static std::string getBaseDirFromPath(const std::string& filePath) {
2730
return filePath.substr(0, filePath.rfind("/") + 1);
2831
}
32+
33+
static void expectFileContentsMatch(
34+
std::string testFilePath,
35+
std::string expectedFilePath) {
36+
auto testFile = std::make_unique<std::ifstream>(testFilePath);
37+
auto expectedFile = std::make_unique<std::ifstream>(expectedFilePath);
38+
39+
while (!expectedFile->eof()) {
40+
if (testFile->eof()) {
41+
FAIL();
42+
}
43+
44+
auto expected = expectedFile->get();
45+
auto test = testFile->get();
46+
EXPECT_EQ(test, expected);
47+
}
48+
}
2949
};
3050

3151
} // namespace fbpcf::io

0 commit comments

Comments
 (0)