привет у меня есть файл мэйн и задание я сделал задание но мне выводит ошибку почему? вот что я сделал #include "task.h"
#include "logged_command_wrapper.h"

/* Курсор влево */
class MoveCursorLeftCommand : public ICommand{
public:
    MoveCursorLeftCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        if (cursorPosition != 0)cursorPosition--;
       
    }
    void AcceptVisitor(CommandVisitor& visitor) override {
        visitor.VisitMoveCursorLeftCommand(*this);
    }
};

/* Курсор вправо */
class MoveCursorRightCommand : public ICommand {
public:
    MoveCursorRightCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        if (buffer.size()  > cursorPosition)cursorPosition++;
    }
    void AcceptVisitor(CommandVisitor& visitor) override {
        visitor.VisitMoveCursorRightCommand(*this);
    }
};


////* Курсор вверх */
class MoveCursorUpCommand : public ICommand {
public:
    MoveCursorUpCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        size_t curstart = buffer.rfind('\n',cursorPosition - 1);

        if (curstart != std::string::npos){
            size_t prstart = buffer.rfind('\n',curstart - 1);
            if (prstart == std::string::npos){
                cursorPosition -= curstart;
            }
            else {
                size_t lencur = cursorPosition - curstart;
                size_t lenpr = curstart - prstart; 
                if (lencur > lenpr ) cursorPosition = prstart + lenpr;
                else cursorPosition = prstart + lencur;
            }
        }
        else {
            cursorPosition = 0;
        }
    }
    void AcceptVisitor(CommandVisitor& visitor) override {
        visitor.VisitMoveCursorUpCommand(*this);
    }
};

class MoveCursorDownCommand : public ICommand {
public:
    MoveCursorDownCommand() {}

    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();

        size_t curend = buffer.find('\n', cursorPosition);
        if (curend != std::string::npos) {
            size_t nextstart = curend + 1;

            if (nextstart < buffer.size()) {
                size_t nextend = buffer.find('\n', nextstart);
                size_t lencur = cursorPosition - (buffer.rfind('\n', cursorPosition - 1) + 1); 
                size_t lennext = (nextend != std::string::npos) ? (nextend - nextstart) : (buffer.size() - nextstart);

                if (lencur > lennext) cursorPosition = nextstart + lennext; 
                else cursorPosition = nextstart + lencur; 
            }
        }
    }

    void AcceptVisitor(CommandVisitor& visitor) override {
        visitor.VisitMoveCursorDownCommand(*this);
    }
};
/* Выделить текст */
class SelectTextCommand : public ICommand {
public:
    explicit SelectTextCommand(size_t selectionSize) : selectionSize_(selectionSize) {}

    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (selectionSize_ == 0 || buffer.empty()) {
            editor.UnselectText();
            return;
        }
        cursorPosition = std::min(cursorPosition, buffer.size());
        size_t selectionend = std::min(cursorPosition + selectionSize_, buffer.size());
        editor.SelectText(cursorPosition, selectionend);
    }

    void AcceptVisitor(CommandVisitor& visitor) override {
        visitor.VisitSelectCommand(*this);
    }

private:
    size_t selectionSize_;
};

/* Ввести текст */
class InsertTextCommand : public ICommand {
public:
    explicit InsertTextCommand(const std::string& text): text_(text){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (editor.HasSelection()){
            auto [selstart,selend] = editor.GetSelection();
            buffer.erase(selstart,selend - selstart);
            cursorPosition = selstart;
        }
        buffer.insert(cursorPosition, text_);
        cursorPosition += text_.size();
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitInsertTextCommand(*this);
    }
private:
    std::string text_;
};

/* Удалить текст */
class DeleteTextCommand : public ICommand {
public:
    DeleteTextCommand() = default;
    explicit DeleteTextCommand(const std::string& text): text_(text){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (editor.HasSelection()){
            auto [selstart,selend] = editor.GetSelection();
            buffer.erase(selstart,selend - selstart);
            cursorPosition = selstart;
        }
        else {
            if (cursorPosition < buffer.size()){
                buffer.erase(cursorPosition , 1);
            }
        }
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitDeleteTextCommand(*this);
    }
private:
    std::string text_;
};

/* Скопировать текст */
class CopyTextCommand : public ICommand {
public:
    CopyTextCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (editor.HasSelection()){
            auto [selstart,selend] = editor.GetSelection();
            clipboard = buffer.substr(selstart,selend - selstart);
        }
        else {
            if (cursorPosition < buffer.size()){
                buffer.substr(cursorPosition , 1);
            }
            else clipboard.clear();
        }
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitCopyTextCommand(*this);
    }
};

/* Вставить скопированный текст */
class PasteTextCommand : public ICommand {
public:
    PasteTextCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (clipboard.empty()){
            return;
        }
        if (editor.HasSelection()){
            auto [selstart,selend] = editor.GetSelection();
            buffer.erase(selstart,selend - selstart);
            cursorPosition = selstart;
        }
        buffer.insert(cursorPosition,clipboard);
        cursorPosition += clipboard.size();
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitPasteTextCommand(*this);
    }
};

/* Привести выделенный текст в ВЕРХНИЙ регистр */
class UppercaseTextCommand : public ICommand {
public:
    UppercaseTextCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (!editor.HasSelection())return;
        auto [selstart,selend] = editor.GetSelection();
        
        for (size_t i = selstart; i < selend ; ++i){
            if (buffer[i] >= 'a' && buffer[i] <= 'z'){
                buffer[i] -= 32;
            }
        }
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitUppercaseTextCommand(*this);
    }
};

/* Привести выделенный текст в нижний регистр */
class LowercaseTextCommand : public ICommand {
public:
    LowercaseTextCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        if (!editor.HasSelection())return;
        auto [selstart,selend] = editor.GetSelection();
        
        for (size_t i = selstart; i < selend ; ++i){
            if (buffer[i] >= 'A' && buffer[i] <= 'Z'){
                buffer[i] += 32;
            }
        }
        editor.UnselectText();
    }
    void AcceptVisitor(CommandVisitor& visitor) override{
        visitor.VisitLowercaseTextCommand(*this);
    }
};

/* Перенести курсор в конец строки */
class MoveToEndCommand : public ICommand {
public:
    MoveToEndCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        size_t curend = buffer.find('\n',cursorPosition);
        if (curend == std::string::npos)cursorPosition = buffer.size();
        else cursorPosition = curend;
    }

    void AcceptVisitor(CommandVisitor& visitor)override {
        visitor.VisitMoveToEndCommand(*this);
    }
};

/* Перенести курсор в начало строки */
class MoveToStartCommand : public ICommand {
public:
    MoveToStartCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        size_t curstart = buffer.rfind('\n',cursorPosition - 1);
        if (curstart == std::string::npos)cursorPosition = 0;
        else cursorPosition = curstart + 1;
    }

    void AcceptVisitor(CommandVisitor& visitor)override {
        visitor.VisitMoveToStartCommand(*this);
    }
};

/* Удалить часть строки, начиная от позиции курсора до первого пробела или конца строки */
class DeleteWordCommand : public ICommand {
public:
    DeleteWordCommand(){}
    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        editor.UnselectText();
        if (cursorPosition >= buffer.size())return;
        size_t spacepos = buffer.find(' ',cursorPosition);
        size_t lineend = buffer.find('\n' , cursorPosition);
        size_t endpos;
        if (spacepos == std::string::npos && lineend == std::string::npos){
            endpos = buffer.size();
        }
        else if (lineend == std::string::npos) {
            endpos = spacepos;
        }
        else if (spacepos == std::string::npos){
            endpos = lineend;
        }
        else {
            if (spacepos > lineend) endpos = lineend;
            else endpos = spacepos;
        }
        buffer.erase(cursorPosition , endpos - cursorPosition);
    }
    void AcceptVisitor(CommandVisitor& visitor)override {
        visitor.VisitDeleteWordCommand(*this);
    }
};

/* Макрос */
class MacroCommand : public ICommand {
public:
    MacroCommand() {}

    void AddSubcommand(CommandPtr subcommand) {
        subcom.emplace_back(std::move(subcommand));
    }

    void Apply(
        std::string& buffer,
        size_t& cursorPosition,
        std::string& clipboard,
        TextEditor& editor
    ) override {
        for (auto& subcommand : subcom) {
            subcommand->Apply(buffer, cursorPosition, clipboard, editor);
        }
    }

    void AcceptVisitor(CommandVisitor& visitor) override {
    }

private:
    std::vector<CommandPtr> subcom;
};

CommandBuilder::CommandBuilder(): type_(CommandBuilder::Type::MoveCursorLeft), selectionSize_(0), text_(), logStreamPtr_(nullptr) {}

CommandBuilder& CommandBuilder::WithType(Type type) {
    type_ = type;
    return *this;
}

CommandBuilder& CommandBuilder::SelectionSize(size_t selectionSize) {
    selectionSize_ = selectionSize;
    return *this;
}

CommandBuilder& CommandBuilder::Text(std::string text) {
    text_ = text; 
    return *this;
}


CommandBuilder& CommandBuilder::LogTo(std::ostream& logStream) {
    logStreamPtr_ = &logStream; 
    return *this;
}

CommandBuilder& CommandBuilder::AddSubcommand(CommandPtr subcommand) {
    subcommands_.emplace_back(std::move(subcommand));
    return *this;
}

CommandPtr CommandBuilder::build() {
    
    CommandPtr command;

        switch (type_) {
            case Type::MoveCursorLeft:
                command = std::make_shared<MoveCursorLeftCommand>();
                break;
            case Type::MoveCursorRight:
                command = std::make_shared<MoveCursorRightCommand>();
                break;
            case Type::MoveCursorUp:
                command = std::make_shared<MoveCursorUpCommand>();
                break;
            case Type::MoveCursorDown:
                command = std::make_shared<MoveCursorDownCommand>();
                break;
            case Type::SelectText:
                command = std::make_shared<SelectTextCommand>(selectionSize_);
                break;
            case Type::InsertText:
                command = std::make_shared<InsertTextCommand>(text_);
                break;
            case Type::DeleteText:
                command = std::make_shared<DeleteTextCommand>();
                break;
            case Type::CopyText:
                command = std::make_shared<CopyTextCommand>();
                break;
            case Type::PasteText:
                command = std::make_shared<PasteTextCommand>();
                break;
            case Type::UppercaseText:
                command = std::make_shared<UppercaseTextCommand>();
                break;
            case Type::LowercaseText:
                command = std::make_shared<LowercaseTextCommand>();
                break;
            case Type::MoveToEnd:
                command = std::make_shared<MoveToEndCommand>();
                break;
            case Type::MoveToStart:
                command = std::make_shared<MoveToStartCommand>();
                break;
            case Type::DeleteWord:
                command = std::make_shared<DeleteWordCommand>();
                break;
            case Type::Macro: {
                auto macro = std::make_shared<MacroCommand>();
                for (const auto& cmd : subcommands_) {
                    macro->AddSubcommand(cmd);
                }
                command = macro;
                break;
            }
        }

        if (logStreamPtr_) {
            command = std::make_shared<LoggedCommandWrapper>(*logStreamPtr_, command);
        }

        return command;
    
}

CommandLoggerVisitor::CommandLoggerVisitor(std::ostream& logStream): logStream_(logStream) {}

void CommandLoggerVisitor::VisitMoveCursorRightCommand(MoveCursorRightCommand& command) {
    logStream_ << "l";
}

void CommandLoggerVisitor::VisitMoveCursorLeftCommand(MoveCursorLeftCommand& command) {
    logStream_ << "h";
}

void CommandLoggerVisitor::VisitMoveCursorUpCommand(MoveCursorUpCommand& command) {
    logStream_ << "k"; 
}

void CommandLoggerVisitor::VisitMoveCursorDownCommand(MoveCursorDownCommand& command) {
    logStream_ << "j"; 
}

void CommandLoggerVisitor::VisitSelectCommand(SelectTextCommand& command) {
    logStream_ << "v";
}

void CommandLoggerVisitor::VisitInsertTextCommand(InsertTextCommand& command) {
    logStream_ << "i"; 
}

void CommandLoggerVisitor::VisitDeleteTextCommand(DeleteTextCommand& command) {
    logStream_ << "d"; 
}

void CommandLoggerVisitor::VisitCopyTextCommand(CopyTextCommand& command) {
    logStream_ << "y"; 
}

void CommandLoggerVisitor::VisitPasteTextCommand(PasteTextCommand& command) {
    logStream_ << "p";
}

void CommandLoggerVisitor::VisitUppercaseTextCommand(UppercaseTextCommand& command) {
    logStream_ << "U"; 
}

void CommandLoggerVisitor::VisitLowercaseTextCommand(LowercaseTextCommand& command) {
    logStream_ << "u"; 
}

void CommandLoggerVisitor::VisitMoveToStartCommand(MoveToStartCommand& command) {
    logStream_ << "0"; 
}

void CommandLoggerVisitor::VisitMoveToEndCommand(MoveToEndCommand& command) {
    logStream_ << "$"; 
}

void CommandLoggerVisitor::VisitDeleteWordCommand(DeleteWordCommand& command) {
    logStream_ << "dE"; 
} а вот файл проверки #include "task.h"
#include <cassert>
#include <sstream>

void ApplyMultiple(TextEditor& editor, const CommandPtr& command, size_t times) {
    for (size_t i = 0; i < times; ++i) {
        editor.ApplyCommand(command);
    }
}

CommandBuilder CB(CommandBuilder::Type t) {
    return CommandBuilder().WithType(t);
}

void TestOneLine() {
    TextEditor editor;
    assert(editor.GetText().empty());
    assert(editor.GetCursorPosition() == 0);
    assert(editor.GetCharUnderCursor() == 0);

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text("Hello world").build());
    assert(editor.GetText() == "Hello world");
    assert(editor.GetCursorPosition() == 11);

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorLeft).build(), 6);
    assert(editor.GetCursorPosition() == 5);
    assert(editor.GetCharUnderCursor() == ' ');

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text(",").build());
    assert(editor.GetText() == "Hello, world");
    assert(editor.GetCursorPosition() == 6);
    assert(editor.GetCharUnderCursor() == ' ');

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToEnd).build());
    assert(editor.GetText() == "Hello, world");
    assert(editor.GetCursorPosition() == 12);
    assert(editor.GetCharUnderCursor() == 0);

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text("!").build());
    assert(editor.GetText() == "Hello, world!");
    assert(editor.GetCursorPosition() == 13);
    assert(editor.GetCharUnderCursor() == 0);

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToStart).build());
    assert(editor.GetText() == "Hello, world!");
    assert(editor.GetCursorPosition() == 0);
    assert(editor.GetCharUnderCursor() == 'H');

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorRight).build(), 8);
    assert(editor.GetText() == "Hello, world!");
    assert(editor.GetCursorPosition() == 8);
    assert(editor.GetCharUnderCursor() == 'o');

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorRight).build(), 22);
    assert(editor.GetText() == "Hello, world!");
    assert(editor.GetCursorPosition() == 13);
    assert(editor.GetCharUnderCursor() == 0);

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorLeft).build(), 57);
    assert(editor.GetText() == "Hello, world!");
    assert(editor.GetCursorPosition() == 0);
    assert(editor.GetCharUnderCursor() == 'H');
}

void TestCopyPaste() {
    TextEditor editor;

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text("Vasya was here\n").build());
    assert(editor.GetText() == "Vasya was here\n");
    assert(editor.GetCursorPosition() == 15);
    assert(editor.GetCharUnderCursor() == 0);

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorUp).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).SelectionSize(15).build());
    assert(editor.GetSelection() == std::make_pair((size_t)0, (size_t)15));
    assert(editor.GetCharUnderCursor() == 'V');

    editor.ApplyCommand(CB(CommandBuilder::Type::CopyText).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).SelectionSize(15).build());
    assert(editor.GetClipboard() == editor.GetText());

    editor.ApplyCommand(CB(CommandBuilder::Type::PasteText).build());  // paste in place of selection
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorUp).build());
    assert(editor.GetClipboard() == editor.GetText());
    assert(editor.GetCharUnderCursor() == 'V');
    assert(editor.GetCursorPosition() == 0);
    assert(!editor.HasSelection());

    editor.ApplyCommand(CB(CommandBuilder::Type::PasteText).build());  // paste on position 0
    assert(editor.GetText() == "Vasya was here\nVasya was here\n");
    assert(editor.GetCharUnderCursor() == 'V');
    assert(editor.GetCursorPosition() == 15);
    assert(!editor.HasSelection());

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToEnd).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text("\nIvan is cool").build());
    assert(editor.GetText() == "Vasya was here\nVasya was here\nIvan is cool\n");
    assert(editor.GetCursorPosition() == editor.GetText().size() - 1);
    assert(editor.GetCharUnderCursor() == '\n');

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorUp).build());
    assert(editor.GetCursorPosition() == 27);
    assert(editor.GetCharUnderCursor() == 'r');

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorUp).build(), 8);
    assert(editor.GetText() == "Vasya was here\nVasya was here\nIvan is cool\n");
    assert(editor.GetCursorPosition() == 12);
    assert(editor.GetCharUnderCursor() == 'r');

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToStart).build());
    assert(editor.GetCursorPosition() == 0);
    assert(editor.GetCharUnderCursor() == 'V');

    CommandPtr macroCommand = CommandBuilder()
            .WithType(CommandBuilder::Type::Macro)
            .AddSubcommand(CB(CommandBuilder::Type::DeleteWord).build())
            .AddSubcommand(CB(CommandBuilder::Type::InsertText).Text("Fedor").build())
            .AddSubcommand(CB(CommandBuilder::Type::MoveCursorDown).build())
            .AddSubcommand(CB(CommandBuilder::Type::MoveToStart).build())
            .build();

    ApplyMultiple(editor, macroCommand, 3);
    assert(editor.GetText() == "Fedor was here\nFedor was here\nFedor is cool\n");

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorLeft).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToStart).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).SelectionSize(5).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::DeleteText).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::DeleteText).build());
    assert(editor.GetCursorPosition() == 30);
    assert(editor.GetCharUnderCursor() == 'i');
    assert(editor.GetText() == "Fedor was here\nFedor was here\nis cool\n");
}

void TestUnselect() {
    TextEditor editor;

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).Text("Who am I\nAyanami Rey\n").build());
    assert(editor.GetText() == "Who am I\nAyanami Rey\n");
    assert(editor.GetCursorPosition() == 21);
    assert(editor.GetCharUnderCursor() == 0);

    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorUp).build());
    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorRight).build(), 4);
    assert(editor.GetText() == "Who am I\nAyanami Rey\n");
    assert(editor.GetCursorPosition() == 13);
    assert(editor.GetCharUnderCursor() == 'a');

    CommandBuilder::Type CommandsToTest[] = {
            CommandBuilder::Type::MoveCursorLeft,
            CommandBuilder::Type::MoveCursorRight,
            CommandBuilder::Type::MoveCursorUp,
            CommandBuilder::Type::MoveCursorDown,
            CommandBuilder::Type::CopyText,
            CommandBuilder::Type::PasteText,
            CommandBuilder::Type::MoveToEnd,
            CommandBuilder::Type::MoveToStart,
            CommandBuilder::Type::DeleteWord,
            CommandBuilder::Type::InsertText,
    };

    for (const auto& command : CommandsToTest) {
        editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).SelectionSize(3).build());
        editor.ApplyCommand(CB(command).Text("123").build());
        assert(!editor.HasSelection());
    }

    assert(editor.GetText() == "Who am I\n123y\n");
    assert(editor.GetCursorPosition() == 12);
    assert(editor.GetCharUnderCursor() == 'y');
}

void TestLogging() {
    TextEditor editor;
    std::stringstream logStream;

    editor.ApplyCommand(CB(CommandBuilder::Type::InsertText).LogTo(logStream).Text("Quick brown fox jumps\nover the lazy dog").build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorUp).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToStart).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveCursorDown).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToEnd).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::MoveToStart).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).LogTo(logStream).SelectionSize(4).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::CopyText).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::DeleteWord).LogTo(logStream).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::PasteText).LogTo(logStream).build());

    assert(editor.GetText() == "Quick brown fox jumps\nover the lazy dog");

    ApplyMultiple(editor, CB(CommandBuilder::Type::MoveCursorLeft).LogTo(logStream).build(), 26);
    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).LogTo(logStream).SelectionSize(5).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::UppercaseText).LogTo(logStream).build());
    assert(editor.GetText() == "QUICK brown fox jumps\nover the lazy dog");

    editor.ApplyCommand(CB(CommandBuilder::Type::SelectText).LogTo(logStream).SelectionSize(5).build());
    editor.ApplyCommand(CB(CommandBuilder::Type::LowercaseText).LogTo(logStream).build());
    assert(editor.GetText() == "quick brown fox jumps\nover the lazy dog");

    CommandPtr macroCommand = CommandBuilder()
            .WithType(CommandBuilder::Type::Macro)
            .AddSubcommand(CB(CommandBuilder::Type::DeleteWord).build())
            .AddSubcommand(CB(CommandBuilder::Type::InsertText).Text("Fedor").build())
            .AddSubcommand(CB(CommandBuilder::Type::MoveCursorDown).build())
            .AddSubcommand(CB(CommandBuilder::Type::MoveToStart).build())
            .LogTo(logStream)
            .build();

    ApplyMultiple(editor, macroCommand, 2);
    assert(editor.GetText() == "Fedor brown fox jumps\nFedor the lazy dog");

    assert(logStream.str() == "ik0j$0vydEphhhhhhhhhhhhhhhhhhhhhhhhhhvUvudEij0dEij0");
}

int main () {
    TestOneLine();
    TestCopyPaste();
    TestUnselect();
    TestLogging();
    return 0;
}
а вот ошибка g++ -c -g -fsanitize=address -std=c++2a -Wall -Werror task.cpp -o task.o
g++ logged_command_wrapper.o main.o task.o text_editor.o -fsanitize=address -o main
ASAN_OPTIONS= ./main
main(36650,0x1f2978c00) malloc: nano zone abandoned due to inability to reserve vm space.
Assertion failed: (editor.GetSelection() == std::make_pair((size_t)0, (size_t)15)), function TestCopyPaste, file main.cpp, line 75.
make: *** [run] Abort trap: 6