#include "gtest/gtest.h" #include "Buffer.h" #include "TestSupport.h" #include "Path.h" #include #define C(x) ((uint32_t)(x)) #define ss(s) std::string(s) TEST(BufferTest, writes_an_identical_file_to_what_is_loaded_if_no_changes_were_performed) { const char * files_to_test[] = { "test/files/empty.txt", "test/files/one_eol.txt", "test/files/two_eol.txt", "test/files/line_endings/cr_format.txt", "test/files/line_endings/crlf_format.txt", "test/files/line_endings/lf_format.txt", "test/files/no_eol_at_eof.txt", "test/files/no_eol_at_eof_crlf.txt", }; for (auto e : files_to_test) { Buffer b(e); ASSERT_TRUE(b.write_to_file("test/tmp/f")); ASSERT_TRUE(Path::is_file("test/tmp/f")); TestSupport::compare_files(e, "test/tmp/f"); } } TEST(BufferTest, writes_an_empty_file_for_an_empty_buffer) { Buffer b; ASSERT_TRUE(b.write_to_file("test/tmp/f")); TestSupport::compare_files("test/files/empty.txt", "test/tmp/f"); } TEST(BufferTest, allows_navigating_using_iterators) { Buffer b("test/files/line_endings/lf_format.txt"); auto iterator = b.add_cursor(); EXPECT_EQ(0u, iterator->line()); ASSERT_EQ(C('H'), **iterator); EXPECT_FALSE(iterator->go_previous_line()); EXPECT_EQ(0u, iterator->line()); ASSERT_EQ(C('H'), **iterator); EXPECT_TRUE(iterator->go_right_in_line(false)); EXPECT_EQ(0u, iterator->line()); ASSERT_EQ(C('e'), **iterator); EXPECT_TRUE(iterator->go_next_line()); EXPECT_EQ(1u, iterator->line()); ASSERT_EQ(C('T'), **iterator); EXPECT_FALSE(iterator->go_left_in_line()); EXPECT_EQ(1u, iterator->line()); ASSERT_EQ(C('T'), **iterator); EXPECT_TRUE(iterator->go_right_in_line(true)); EXPECT_EQ(1u, iterator->line()); ASSERT_EQ(C('h'), **iterator); EXPECT_FALSE(iterator->go_next_line()); EXPECT_EQ(1u, iterator->line()); ASSERT_EQ(C('h'), **iterator); EXPECT_TRUE(iterator->go_previous_line()); EXPECT_EQ(0u, iterator->line()); ASSERT_EQ(C('H'), **iterator); } TEST(BufferTest, allows_navigating_using_iterators2) { Buffer b("test/files/blank_lines.txt"); auto iterator = b.add_cursor(); EXPECT_EQ(0u, iterator->line()); EXPECT_EQ(C('a'), **iterator); EXPECT_TRUE(iterator->go_next_line()); EXPECT_EQ(1u, iterator->line()); EXPECT_EQ(C('\n'), **iterator); EXPECT_FALSE(iterator->go_start_of_line()); EXPECT_EQ(1u, iterator->line()); EXPECT_EQ(C('\n'), **iterator); EXPECT_FALSE(iterator->go_end_of_line(false)); EXPECT_EQ(1u, iterator->line()); EXPECT_EQ(C('\n'), **iterator); EXPECT_FALSE(iterator->go_end_of_line(true)); EXPECT_EQ(1u, iterator->line()); EXPECT_EQ(C('\n'), **iterator); EXPECT_TRUE(iterator->go_next_line()); EXPECT_EQ(2u, iterator->line()); EXPECT_EQ(C('d'), **iterator); EXPECT_TRUE(iterator->go_previous_line()); EXPECT_EQ(1u, iterator->line()); EXPECT_EQ(C('\n'), **iterator); EXPECT_TRUE(iterator->go_previous_line()); EXPECT_EQ(0u, iterator->line()); EXPECT_EQ(C('a'), **iterator); } TEST(BufferTest, allows_inserting_and_erasing_characters) { std::string s("abc\ndef\nghi\n"); Buffer b((const uint8_t *)&s[0], s.size()); auto it = b.add_cursor(); b.insert_code_point(*it, C('1')); EXPECT_EQ(ss("1abc\ndef\nghi\n"), b.get_string()); EXPECT_EQ(C('a'), **it); it->go_end_of_line(true); b.insert_code_point(*it, C('$')); EXPECT_EQ(ss("1abc$\ndef\nghi\n"), b.get_string()); EXPECT_EQ(C('\n'), **it); b.erase_code_point(*it); EXPECT_EQ(ss("1abc$def\nghi\n"), b.get_string()); EXPECT_EQ(C('d'), **it); } TEST(BufferTest, adds_a_newline_after_inserted_character_when_inserting_in_an_empty_buffer) { Buffer b; auto it = b.add_cursor(); EXPECT_EQ(0u, it->offset()); b.insert_code_point(*it, C('J')); EXPECT_EQ(ss("J\n"), b.get_string()); EXPECT_EQ(C('\n'), **it); }