Files
kte/tests/test_buffer_io.cc
Kyle Isom 8ec0d6ac41 Add benchmarks, migration tests, and dev guide
Add benchmarks for core operations, migration edge case tests, improved
buffer I/O tests, and developer guide

- Introduced `test_benchmarks.cc` for performance benchmarking of key
  operations in `PieceTable` and `Buffer`, including syntax highlighting
  and iteration patterns.
- Added `test_migration_coverage.cc` to provide comprehensive tests for
  migration of `Buffer::Rows()` to `PieceTable` APIs, with edge cases,
  boundary handling, and consistency checks.
- Enhanced `test_buffer_io.cc` with additional cases for save/load
  workflows, file handling, and better integration with the core API.
- Documented architectural details and core concepts in a new
  `DEVELOPER_GUIDE.md`. Highlighted design principles, code
  organization, and contribution workflows.
2026-02-17 16:08:23 -08:00

104 lines
2.7 KiB
C++

/*
* test_buffer_io.cc - Tests for Buffer file I/O operations
*
* This file validates the Buffer's file handling capabilities, which are
* critical for a text editor. Buffer manages the relationship between
* in-memory content and files on disk.
*
* Key functionality tested:
* - SaveAs() creates a new file and makes the buffer file-backed
* - Save() writes to the existing file (requires file-backed buffer)
* - OpenFromFile() loads existing files or creates empty buffers for new files
* - The dirty flag is properly managed across save operations
*
* These tests demonstrate the Buffer I/O contract that commands rely on.
* When adding new file operations, follow these patterns.
*/
#include "Test.h"
#include <fstream>
#include <cstdio>
#include <string>
#include "Buffer.h"
static std::string
read_all(const std::string &path)
{
std::ifstream in(path, std::ios::binary);
return std::string((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
}
TEST (Buffer_SaveAs_and_Save_new_file)
{
const std::string path = "./.kte_ut_buffer_io_1.tmp";
std::remove(path.c_str());
Buffer b;
// insert two lines
b.insert_text(0, 0, std::string("Hello, world!\n"));
b.insert_text(1, 0, std::string("Second line\n"));
std::string err;
ASSERT_TRUE(b.SaveAs(path, err));
ASSERT_EQ(err.empty(), true);
// append another line then Save()
b.insert_text(2, 0, std::string("Third\n"));
b.SetDirty(true);
ASSERT_TRUE(b.Save(err));
ASSERT_EQ(err.empty(), true);
std::string got = read_all(path);
ASSERT_EQ(got, std::string("Hello, world!\nSecond line\nThird\n"));
std::remove(path.c_str());
}
TEST (Buffer_Save_after_Open_existing)
{
const std::string path = "./.kte_ut_buffer_io_2.tmp";
std::remove(path.c_str());
{
std::ofstream out(path, std::ios::binary);
out << "abc\n123\n";
}
Buffer b;
std::string err;
ASSERT_TRUE(b.OpenFromFile(path, err));
ASSERT_EQ(err.empty(), true);
b.insert_text(2, 0, std::string("tail\n"));
b.SetDirty(true);
ASSERT_TRUE(b.Save(err));
ASSERT_EQ(err.empty(), true);
std::string got = read_all(path);
ASSERT_EQ(got, std::string("abc\n123\ntail\n"));
std::remove(path.c_str());
}
TEST (Buffer_Open_nonexistent_then_SaveAs)
{
const std::string path = "./.kte_ut_buffer_io_3.tmp";
std::remove(path.c_str());
Buffer b;
std::string err;
ASSERT_TRUE(b.OpenFromFile(path, err));
ASSERT_EQ(err.empty(), true);
ASSERT_EQ(b.IsFileBacked(), false);
b.insert_text(0, 0, std::string("hello, world"));
b.insert_text(0, 12, std::string("\n"));
b.SetDirty(true);
ASSERT_TRUE(b.SaveAs(path, err));
ASSERT_EQ(err.empty(), true);
std::string got = read_all(path);
ASSERT_EQ(got, std::string("hello, world\n"));
std::remove(path.c_str());
}