aboutsummaryrefslogtreecommitdiff
path: root/tests/fdstream/driver.cxx
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2016-07-02 17:21:54 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2016-07-07 17:39:46 +0300
commit5b1c20f2315cd7fc624ffd31abdcc03b409bfcb2 (patch)
treec5c7b76dead92292b84586bda1b1256170195c48 /tests/fdstream/driver.cxx
parent15634965e8f0ab753898f5607ba11288556d1235 (diff)
Add cpfile()
Diffstat (limited to 'tests/fdstream/driver.cxx')
-rw-r--r--tests/fdstream/driver.cxx135
1 files changed, 135 insertions, 0 deletions
diff --git a/tests/fdstream/driver.cxx b/tests/fdstream/driver.cxx
new file mode 100644
index 0000000..3972473
--- /dev/null
+++ b/tests/fdstream/driver.cxx
@@ -0,0 +1,135 @@
+// file : tests/fdstream/driver.cxx -*- C++ -*-
+// copyright : Copyright (c) 2014-2016 Code Synthesis Ltd
+// license : MIT; see accompanying LICENSE file
+
+#include <string>
+#include <cassert>
+#include <system_error>
+
+#include <butl/path>
+#include <butl/fdstream>
+#include <butl/filesystem>
+
+using namespace std;
+using namespace butl;
+
+static const string text1 ("ABCDEF\nXYZ");
+static const string text2 ("12"); // Keep shorter than text1.
+static const string text3 ("ABCDEF\r\nXYZ");
+
+static string
+from_file (const path& f, fdopen_mode m = fdopen_mode::none)
+{
+ ifdstream ifs (fdopen (f, m | fdopen_mode::in));
+ ifs.exceptions (ifdstream::badbit);
+
+ string s;
+ getline (ifs, s, '\0');
+ return s;
+}
+
+static void
+to_file (const path& f, const string& s, fdopen_mode m = fdopen_mode::none)
+{
+ ofdstream ofs (fdopen (f, m | fdopen_mode::out));
+ ofs.exceptions (ofdstream::badbit | ofdstream::failbit);
+ ofs << s;
+}
+
+int
+main ()
+{
+ dir_path td (dir_path::temp_directory () / dir_path ("butl-fdstream"));
+
+ // Recreate the temporary directory (that possibly exists from the previous
+ // faulty run) for the test files. Delete the directory only if the test
+ // succeeds to simplify the failure research.
+ //
+ try_rmdir_r (td);
+ assert (try_mkdir (td) == mkdir_status::success);
+
+ path f (td / path ("file"));
+
+ try
+ {
+ fdopen (f, fdopen_mode::out); // fdopen_mode::create is missed.
+ assert (false);
+ }
+ catch (const system_error&)
+ {
+ }
+
+ // Read from the newly created empty file.
+ //
+ assert (from_file (f, fdopen_mode::create) == "");
+ assert (try_rmfile (f) == rmfile_status::success);
+
+ to_file (f, text1, fdopen_mode::create);
+ assert (from_file (f) == text1);
+
+ // Read from the file opened in R/W mode.
+ //
+ assert (from_file (f, fdopen_mode::out) == text1);
+
+ try
+ {
+ // Fail to create if the file already exists.
+ //
+ fdopen (
+ f, fdopen_mode::out | fdopen_mode::create | fdopen_mode::exclusive);
+
+ assert (false);
+ }
+ catch (const system_error&)
+ {
+ }
+
+ // Write text2 over text1.
+ //
+ to_file (f, text2);
+ string s (text2);
+ s += string (text1, text2.size ());
+ assert (from_file (f) == s);
+
+ // Truncate before reading.
+ //
+ assert (from_file (f, fdopen_mode::out | fdopen_mode::truncate) == "");
+
+ // Append to the file.
+ //
+ to_file (f, text1, fdopen_mode::truncate);
+ to_file (f, text2, fdopen_mode::append);
+ assert (from_file (f) == text1 + text2);
+
+#ifndef _WIN32
+
+ // Fail for an existing symlink to unexistent file.
+ //
+ path link (td / path ("link"));
+ mksymlink (td / path ("unexistent"), link);
+
+ try
+ {
+ fdopen (
+ link, fdopen_mode::out | fdopen_mode::create | fdopen_mode::exclusive);
+
+ assert (false);
+ }
+ catch (const system_error&)
+ {
+ }
+
+#else
+
+ // Check translation modes.
+ //
+ to_file (f, text1, fdopen_mode::truncate);
+ assert (from_file (f, fdopen_mode::binary) == text3);
+
+ to_file (f, text3, fdopen_mode::truncate | fdopen_mode::binary);
+ assert (from_file (f) == text1);
+
+#endif
+
+ rmdir_r (td);
+}