From c3f2fe9bcd97ff83b4f6b4371d2c396f762a5553 Mon Sep 17 00:00:00 2001 From: Brandon Taylor Date: Tue, 24 Sep 2024 00:11:24 +0100 Subject: [PATCH] coverage --- .github/workflows/workflow.yaml | 4 +- include/justly/justly.hpp | 1 - src/chord/ChordsModel.cpp | 10 -- src/note/Note.cpp | 11 +- src/note/NotesModel.cpp | 4 +- src/note/SetNotesCells.cpp | 6 -- src/other/ItemModel.cpp | 3 +- src/other/justly.cpp | 36 ++++--- src/percussion/Percussion.cpp | 26 +++-- src/percussion/PercussionsModel.cpp | 4 +- src/song/SongEditor.cpp | 46 ++++---- src/song/SongEditor.hpp | 4 +- tests/Tester.cpp | 157 +++++++++++++++++----------- tests/Tester.h | 3 + 14 files changed, 166 insertions(+), 149 deletions(-) diff --git a/.github/workflows/workflow.yaml b/.github/workflows/workflow.yaml index 1884e954..e01596aa 100644 --- a/.github/workflows/workflow.yaml +++ b/.github/workflows/workflow.yaml @@ -126,8 +126,8 @@ jobs: - name: Build with tests run: cmake --build with_tests --config Release - - name: Test on Unix - if: matrix.os != 'windows-latest' + - name: Test on Ubuntu (TODO add MacOS) + if: matrix.os == 'ubuntu-24.04' run: cd with_tests; QT_QPA_PLATFORM=offscreen ctest --build-config Release --verbose - name: Test on Windows diff --git a/include/justly/justly.hpp b/include/justly/justly.hpp index d3d161f8..b68e269c 100644 --- a/include/justly/justly.hpp +++ b/include/justly/justly.hpp @@ -59,7 +59,6 @@ void JUSTLY_EXPORT set_editor(const QAbstractItemView *table_view_pointer, const QVariant &new_value); void JUSTLY_EXPORT undo(const SongEditor *song_editor_pointer); -void JUSTLY_EXPORT redo(const SongEditor *song_editor_pointer); void JUSTLY_EXPORT trigger_insert_after(const SongEditor *song_editor_pointer); void JUSTLY_EXPORT trigger_insert_into(const SongEditor *song_editor_pointer); diff --git a/src/chord/ChordsModel.cpp b/src/chord/ChordsModel.cpp index e36ee669..dd4f0a98 100644 --- a/src/chord/ChordsModel.cpp +++ b/src/chord/ChordsModel.cpp @@ -258,16 +258,6 @@ auto ChordsModel::setData(const QModelIndex &index, const QVariant &new_value, return true; } -void insert_chord(ChordsModel *chords_model_pointer, qsizetype chord_number, - const Chord &new_chord) { - Q_ASSERT(chords_model_pointer != nullptr); - auto &chords = chords_model_pointer->chords; - - chords_model_pointer->begin_insert_rows(chord_number, 1); - chords.insert(chords.begin() + static_cast(chord_number), new_chord); - chords_model_pointer->end_insert_rows(); -} - void insert_chords(ChordsModel &chords_model, qsizetype first_chord_number, const QList &new_chords) { auto &chords = chords_model.chords; diff --git a/src/note/Note.cpp b/src/note/Note.cpp index 8cfd42f4..8ab25387 100644 --- a/src/note/Note.cpp +++ b/src/note/Note.cpp @@ -88,12 +88,11 @@ void json_to_notes(QList &new_notes, const nlohmann::json &json_notes, std::back_inserter(new_notes), [](const nlohmann::json &json_note) -> Note { Note note; - if (json_note.contains("instrument")) { - const auto &instrument_value = json_note["instrument"]; - Q_ASSERT(instrument_value.is_string()); - note.instrument_pointer = get_instrument_pointer( - QString::fromStdString(instrument_value.get())); - } + Q_ASSERT(json_note.contains("instrument")); + const auto &instrument_value = json_note["instrument"]; + Q_ASSERT(instrument_value.is_string()); + note.instrument_pointer = get_instrument_pointer( + QString::fromStdString(instrument_value.get())); if (json_note.contains("interval")) { note.interval = json_to_interval(json_note["interval"]); } diff --git a/src/note/NotesModel.cpp b/src/note/NotesModel.cpp index 4c4b572f..9dd007cf 100644 --- a/src/note/NotesModel.cpp +++ b/src/note/NotesModel.cpp @@ -48,9 +48,7 @@ NotesModel::NotesModel(ChordsModel *parent_chords_model_pointer_input, } auto NotesModel::rowCount(const QModelIndex & /*parent_index*/) const -> int { - if (notes_pointer == nullptr) { - return 0; - } + Q_ASSERT(notes_pointer != nullptr); return static_cast(notes_pointer->size()); } diff --git a/src/note/SetNotesCells.cpp b/src/note/SetNotesCells.cpp index dc6b7520..ead703ef 100644 --- a/src/note/SetNotesCells.cpp +++ b/src/note/SetNotesCells.cpp @@ -14,9 +14,6 @@ static void replace_note_cells(NotesModel& notes_model, qsizetype first_note_number, NoteColumn left_column, NoteColumn right_column, const QList &new_notes) { - qInfo("here"); - qInfo() << "left column" << left_column; - qInfo() << "right column" << right_column; auto *notes_pointer = notes_model.notes_pointer; Q_ASSERT(notes_pointer != nullptr); auto number_of_notes = new_notes.size(); @@ -26,14 +23,11 @@ static void replace_note_cells(NotesModel& notes_model, const auto &new_note = new_notes.at(replace_number); for (auto note_column = left_column; note_column <= right_column; note_column = static_cast(note_column + 1)) { - qInfo("here"); - qInfo() << "column" << note_column; switch (note_column) { case note_instrument_column: note.instrument_pointer = new_note.instrument_pointer; break; case note_interval_column: - qInfo() << QVariant::fromValue(new_note.interval).toString(); note.interval = new_note.interval; break; case note_beats_column: diff --git a/src/other/ItemModel.cpp b/src/other/ItemModel.cpp index e33d4677..dd88446c 100644 --- a/src/other/ItemModel.cpp +++ b/src/other/ItemModel.cpp @@ -2,7 +2,6 @@ #include #include -#include #include #include @@ -43,7 +42,7 @@ auto ItemModel::is_column_editable(int /*column_number*/) const -> bool { void ItemModel::edited_cells(qsizetype first_row_number, qsizetype number_of_rows, int left_column, int right_column) { - emit dataChanged( + dataChanged( index(first_row_number, left_column), index(first_row_number + number_of_rows - 1, right_column), {Qt::DisplayRole, Qt::EditRole}); diff --git a/src/other/justly.cpp b/src/other/justly.cpp index 2c028c49..03b6635a 100644 --- a/src/other/justly.cpp +++ b/src/other/justly.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include // IWYU pragma: keep @@ -19,6 +20,7 @@ #include "chord/ChordsModel.hpp" #include "instrument/Instrument.hpp" #include "interval/Interval.hpp" +#include "justly/ChordColumn.hpp" #include "note/NotesModel.hpp" #include "percussion/PercussionsModel.hpp" #include "percussion_instrument/PercussionInstrument.hpp" @@ -96,28 +98,37 @@ auto get_table_view_pointer(const SongEditor *song_editor_pointer) return song_editor_pointer->table_view_pointer; } -auto get_chords_model_pointer(const SongEditor *song_editor_pointer) -> QAbstractItemModel * { +auto get_chords_model_pointer(const SongEditor *song_editor_pointer) + -> QAbstractItemModel * { Q_ASSERT(song_editor_pointer != nullptr); return song_editor_pointer->chords_model_pointer; }; -auto get_notes_model_pointer(const SongEditor *song_editor_pointer) -> QAbstractItemModel * { +auto get_notes_model_pointer(const SongEditor *song_editor_pointer) + -> QAbstractItemModel * { Q_ASSERT(song_editor_pointer != nullptr); return song_editor_pointer->notes_model_pointer; }; -auto get_percussions_model_pointer(const SongEditor *song_editor_pointer) -> QAbstractItemModel * { +auto get_percussions_model_pointer(const SongEditor *song_editor_pointer) + -> QAbstractItemModel * { return song_editor_pointer->percussions_model_pointer; }; -void trigger_edit_notes(SongEditor *song_editor_pointer, qsizetype chord_number) { +void trigger_edit_notes(SongEditor *song_editor_pointer, + qsizetype chord_number) { Q_ASSERT(song_editor_pointer != nullptr); - song_editor_pointer->trigger_edit_notes(chord_number); + song_editor_pointer->table_view_pointer->doubleClicked( + song_editor_pointer->chords_model_pointer->index(chord_number, + chord_notes_column)); }; -void trigger_edit_percussions(SongEditor *song_editor_pointer, qsizetype chord_number) { +void trigger_edit_percussions(SongEditor *song_editor_pointer, + qsizetype chord_number) { Q_ASSERT(song_editor_pointer != nullptr); - song_editor_pointer->trigger_edit_percussions(chord_number); + song_editor_pointer->table_view_pointer->doubleClicked( + song_editor_pointer->chords_model_pointer->index( + chord_number, chord_percussions_column)); }; void trigger_back_to_chords(const SongEditor *song_editor_pointer) { @@ -203,22 +214,17 @@ void set_editor(const QAbstractItemView *table_view_pointer, cell_editor_pointer->setProperty( cell_editor_meta_object->userProperty().name(), new_value); - auto *delegate_pointer = - table_view_pointer->itemDelegate(); + auto *delegate_pointer = table_view_pointer->itemDelegate(); Q_ASSERT(delegate_pointer != nullptr); - delegate_pointer->setModelData( - cell_editor_pointer, table_view_pointer->model(), index); + delegate_pointer->setModelData(cell_editor_pointer, + table_view_pointer->model(), index); } void undo(const SongEditor *song_editor_pointer) { Q_ASSERT(song_editor_pointer != nullptr); song_editor_pointer->undo_stack_pointer->undo(); }; -void redo(const SongEditor *song_editor_pointer) { - Q_ASSERT(song_editor_pointer != nullptr); - song_editor_pointer->undo_stack_pointer->redo(); -}; void trigger_insert_after(const SongEditor *song_editor_pointer) { Q_ASSERT(song_editor_pointer != nullptr); diff --git a/src/percussion/Percussion.cpp b/src/percussion/Percussion.cpp index bd70b7db..d03c5e2d 100644 --- a/src/percussion/Percussion.cpp +++ b/src/percussion/Percussion.cpp @@ -95,20 +95,18 @@ void json_to_percussions(QList &new_percussions, std::back_inserter(new_percussions), [](const nlohmann::json &json_percussion) -> Percussion { Percussion percussion; - if (json_percussion.contains("set")) { - const auto &percussion_set_value = json_percussion["set"]; - Q_ASSERT(percussion_set_value.is_string()); - percussion.percussion_set_pointer = get_percussion_set_pointer( - QString::fromStdString(percussion_set_value.get())); - } - if (json_percussion.contains("instrument")) { - const auto &instrument_value = - json_percussion["instrument"]; - Q_ASSERT(instrument_value.is_string()); - percussion.percussion_instrument_pointer = - get_percussion_instrument_pointer( - QString::fromStdString(instrument_value.get())); - } + Q_ASSERT(json_percussion.contains("set")); + const auto &percussion_set_value = json_percussion["set"]; + Q_ASSERT(percussion_set_value.is_string()); + percussion.percussion_set_pointer = get_percussion_set_pointer( + QString::fromStdString(percussion_set_value.get())); + Q_ASSERT(json_percussion.contains("instrument")); + const auto &instrument_value = + json_percussion["instrument"]; + Q_ASSERT(instrument_value.is_string()); + percussion.percussion_instrument_pointer = + get_percussion_instrument_pointer( + QString::fromStdString(instrument_value.get())); if (json_percussion.contains("beats")) { percussion.beats = json_to_rational(json_percussion["beats"]); } diff --git a/src/percussion/PercussionsModel.cpp b/src/percussion/PercussionsModel.cpp index 384740a5..1e17509d 100644 --- a/src/percussion/PercussionsModel.cpp +++ b/src/percussion/PercussionsModel.cpp @@ -45,9 +45,7 @@ PercussionsModel::PercussionsModel(QUndoStack *undo_stack_pointer_input, auto PercussionsModel::rowCount(const QModelIndex & /*parent_index*/) const -> int { - if (percussions_pointer == nullptr) { - return 0; - } + Q_ASSERT(percussions_pointer != nullptr); return static_cast(percussions_pointer->size()); } diff --git a/src/song/SongEditor.cpp b/src/song/SongEditor.cpp index d7dc27ed..c4be86f9 100644 --- a/src/song/SongEditor.cpp +++ b/src/song/SongEditor.cpp @@ -300,6 +300,7 @@ SongEditor::SongEditor(QWidget *parent_pointer, Qt::WindowFlags flags) play_action_pointer(new QAction(tr("&Play selection"), this)), stop_playing_action_pointer(new QAction(tr("&Stop playing"), this)), save_action_pointer(new QAction(tr("&Save"), this)), + open_action_pointer(new QAction(tr("&Open"), this)), settings_pointer(get_settings_pointer()), event_pointer(new_fluid_event()), sequencer_pointer(new_fluid_sequencer2(0)), @@ -348,8 +349,7 @@ SongEditor::SongEditor(QWidget *parent_pointer, Qt::WindowFlags flags) auto *file_menu_pointer = std::make_unique(tr("&File"), this).release(); - auto *open_action_pointer = - std::make_unique(tr("&Open"), file_menu_pointer).release(); + file_menu_pointer->addAction(open_action_pointer); connect(open_action_pointer, &QAction::triggered, this, [this]() { if (undo_stack_pointer->isClean() || verify_discard_changes()) { @@ -774,13 +774,16 @@ SongEditor::SongEditor(QWidget *parent_pointer, Qt::WindowFlags flags) connect(table_view_pointer, &QAbstractItemView::doubleClicked, this, [this](const QModelIndex &index) { - Q_ASSERT(current_model_type == chords_type); - auto row = index.row(); - auto column = index.column(); - if (column == chord_notes_column) { - trigger_edit_notes(row); - } else if (column == chord_percussions_column) { - trigger_edit_percussions(row); + if (current_model_type == chords_type) { + auto row = index.row(); + auto column = index.column(); + if (column == chord_notes_column) { + undo_stack_pointer->push( + std::make_unique(this, row).release()); + } else if (column == chord_percussions_column) { + undo_stack_pointer->push( + std::make_unique(this, row).release()); + } } }); @@ -854,14 +857,9 @@ void SongEditor::set_model(QAbstractItemModel *model_pointer) const { update_actions(); } -void SongEditor::trigger_edit_notes(qsizetype chord_number) { - undo_stack_pointer->push( - std::make_unique(this, chord_number).release()); -} - -void SongEditor::trigger_edit_percussions(qsizetype chord_number) { - undo_stack_pointer->push( - std::make_unique(this, chord_number).release()); +void SongEditor::is_chords_now(bool is_chords) const { + back_to_chords_action_pointer->setEnabled(!is_chords); + open_action_pointer->setEnabled(is_chords); } void SongEditor::edit_notes(qsizetype chord_number) { @@ -874,7 +872,7 @@ void SongEditor::edit_notes(qsizetype chord_number) { notes_model_pointer->parent_chord_number = chord_number; notes_model_pointer->end_reset_model(); current_model_type = notes_type; - back_to_chords_action_pointer->setEnabled(true); + is_chords_now(false); set_model(notes_model_pointer); } @@ -887,7 +885,7 @@ void SongEditor::edit_percussions(qsizetype chord_number) { &chords_model_pointer->chords[chord_number].percussions; percussions_model_pointer->end_reset_model(); current_model_type = percussion_type; - back_to_chords_action_pointer->setEnabled(true); + is_chords_now(false); set_model(percussions_model_pointer); } @@ -899,7 +897,7 @@ void SongEditor::notes_to_chords() { notes_model_pointer->end_reset_model(); current_model_type = chords_type; current_chord_number = -1; - back_to_chords_action_pointer->setEnabled(false); + is_chords_now(true); } void SongEditor::percussions_to_chords() { @@ -909,7 +907,7 @@ void SongEditor::percussions_to_chords() { percussions_model_pointer->end_reset_model(); current_model_type = chords_type; current_chord_number = -1; - back_to_chords_action_pointer->setEnabled(false); + is_chords_now(true); } void SongEditor::back_to_chords() { @@ -1090,7 +1088,7 @@ void SongEditor::start_real_time() { fluid_settings_setstr(settings_pointer, "audio.driver", "pulseaudio"); #else fluid_settings_setstr(settings_pointer, "audio.driver", - default_driver.c_str()); + default_driver.toStdString().c_str()); #endif #ifndef NO_REALTIME_AUDIO @@ -1404,10 +1402,6 @@ void SongEditor::open_file(const QString &filename) { get_json_double(json_song, "starting_tempo")); } - if (current_model_type != chords_type) { - back_to_chords(); - } - const auto &chords = chords_model_pointer->chords; if (!chords.empty()) { Q_ASSERT(chords_model_pointer != nullptr); diff --git a/src/song/SongEditor.hpp b/src/song/SongEditor.hpp index 67e6fb86..15aefdb1 100644 --- a/src/song/SongEditor.hpp +++ b/src/song/SongEditor.hpp @@ -89,6 +89,7 @@ struct SongEditor : public QMainWindow { // io actions QAction *const save_action_pointer; + QAction *const open_action_pointer; // fluidsynth fields fluid_settings_t *const settings_pointer; @@ -119,9 +120,8 @@ struct SongEditor : public QMainWindow { // mode methods void connect_model(const QAbstractItemModel *model_pointer) const; void set_model(QAbstractItemModel *model_pointer) const; - void trigger_edit_notes(qsizetype chord_number); void edit_notes(qsizetype chord_number); - void trigger_edit_percussions(qsizetype chord_number); + void is_chords_now(bool is_chords) const; void edit_percussions(qsizetype chord_number); void notes_to_chords(); void percussions_to_chords(); diff --git a/tests/Tester.cpp b/tests/Tester.cpp index f480c25e..ef76978c 100644 --- a/tests/Tester.cpp +++ b/tests/Tester.cpp @@ -361,9 +361,10 @@ static void test_column_flags_editable(const QAbstractItemModel *model_pointer, int column, bool is_editable) { Q_ASSERT(model_pointer != nullptr); - qInfo() << is_editable; auto uneditable_flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable; - QCOMPARE(model_pointer->index(0, column).flags(), is_editable ? (uneditable_flags | Qt::ItemIsEditable) : uneditable_flags); + QCOMPARE(model_pointer->index(0, column).flags(), + is_editable ? (uneditable_flags | Qt::ItemIsEditable) + : uneditable_flags); } static void test_number_of_columns(const QAbstractItemModel *model_pointer, @@ -373,14 +374,11 @@ static void test_number_of_columns(const QAbstractItemModel *model_pointer, static void test_set_values(const SongEditor *song_editor_pointer, const std::vector &rows) { - const auto* table_view_pointer = get_table_view_pointer(song_editor_pointer); + const auto *table_view_pointer = get_table_view_pointer(song_editor_pointer); for (const auto &row : rows) { - + const auto ©_index = row.first_index; const auto &paste_index = row.second_index; - qInfo() << copy_index.column(); - qInfo() << paste_index.column(); - auto copy_value = copy_index.data(); auto paste_value = paste_index.data(); @@ -426,7 +424,6 @@ static void test_delete_cells(SongEditor *song_editor_pointer, get_selector_pointer(get_table_view_pointer(song_editor_pointer)); for (const auto &index : indices) { - qInfo() << "Column number " << index.column(); const auto &old_value = index.data(); selector_pointer->select(index, QItemSelectionModel::Select); @@ -644,27 +641,27 @@ void Tester::test_to_strings() const { for (const auto &row : std::vector({ ToStringRow( {chords_model_pointer->index(0, chord_interval_column), ""}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(1, chord_interval_column), "3"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(2, chord_interval_column), "/2"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(3, chord_interval_column), "3/2"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(4, chord_interval_column), "o1"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(5, chord_interval_column), "3o1"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(6, chord_interval_column), "/2o1"}), - ToStringRow( - {chords_model_pointer->index(7, chord_interval_column), "3/2o1"}), - ToStringRow( + ToStringRow({chords_model_pointer->index(7, chord_interval_column), + "3/2o1"}), + ToStringRow( {chords_model_pointer->index(0, chord_beats_column), ""}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(1, chord_beats_column), "3"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(2, chord_beats_column), "/2"}), - ToStringRow( + ToStringRow( {chords_model_pointer->index(3, chord_beats_column), "3/2"}), })) { QCOMPARE(row.index.data().toString(), row.text); @@ -676,16 +673,10 @@ void Tester::test_chords_count() const { } void Tester::test_notes_count() const { - for (const auto &row : std::vector({ - CountRow({0, 0}), - CountRow({1, 8}), - CountRow({2, 0}), - CountRow({3, 0}), - CountRow({4, 0}), - CountRow({5, 0}), - CountRow({6, 0}), - CountRow({7, 0}) - })) { + for (const auto &row : + std::vector({CountRow({0, 0}), CountRow({1, 8}), CountRow({2, 0}), + CountRow({3, 0}), CountRow({4, 0}), CountRow({5, 0}), + CountRow({6, 0}), CountRow({7, 0})})) { trigger_edit_notes(song_editor_pointer, row.chord_number); QCOMPARE(notes_model_pointer->rowCount(), row.number); undo(song_editor_pointer); @@ -693,22 +684,23 @@ void Tester::test_notes_count() const { } void Tester::test_percussions_count() const { - for (const auto &row : std::vector({ - CountRow({0, 0}), - CountRow({1, 4}), - CountRow({2, 0}), - CountRow({3, 0}), - CountRow({4, 0}), - CountRow({5, 0}), - CountRow({6, 0}), - CountRow({7, 0}) - })) { + for (const auto &row : + std::vector({CountRow({0, 0}), CountRow({1, 4}), CountRow({2, 0}), + CountRow({3, 0}), CountRow({4, 0}), CountRow({5, 0}), + CountRow({6, 0}), CountRow({7, 0})})) { trigger_edit_percussions(song_editor_pointer, row.chord_number); QCOMPARE(percussions_model_pointer->rowCount(), row.number); undo(song_editor_pointer); } } +void Tester::test_back_to_chords() const { + trigger_edit_percussions(song_editor_pointer, 0); + trigger_back_to_chords(song_editor_pointer); + undo(song_editor_pointer); + undo(song_editor_pointer); +} + void Tester::test_number_of_chord_columns() const { test_number_of_columns(chords_model_pointer, NUMBER_OF_CHORD_COLUMNS); } @@ -869,6 +861,16 @@ void Tester::test_chord_frequencies() const { } } +void Tester::test_note_frequencies() const { + trigger_edit_notes(song_editor_pointer, 1); + set_starting_key(song_editor_pointer, A_FREQUENCY); + QCOMPARE(notes_model_pointer->index(0, chord_interval_column) + .data(Qt::StatusTipRole), + "660 Hz; E5 + 2 cents"); + undo(song_editor_pointer); + undo(song_editor_pointer); +} + void Tester::test_get_unsupported_chord_role() const { test_get_unsupported_role(chords_model_pointer); } @@ -1038,22 +1040,44 @@ void Tester::test_percussion_remove_rows() const { void Tester::test_bad_chord_pastes() { test_bad_pastes( chords_model_pointer->index(0, 0), - std::vector({BadPasteRow({"", "not a mime", "Cannot paste not a mime into destination needing chords cells"}), - BadPasteRow({"", NOTES_CELLS_MIME, "Cannot paste notes cells into destination needing chords cells"}), - BadPasteRow({"[", CHORDS_CELLS_MIME, "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal"}), - BadPasteRow({"[]", CHORDS_CELLS_MIME, "Nothing to paste!"}), - BadPasteRow({"{\"a\": 1}", CHORDS_CELLS_MIME, "At of {\"a\":1} - required property 'left_column' not found in object\n"})})); + std::vector( + {BadPasteRow({"", "not a mime", + "Cannot paste not a mime into destination needing " + "chords cells"}), + BadPasteRow({"", NOTES_CELLS_MIME, + "Cannot paste notes cells into destination needing " + "chords cells"}), + BadPasteRow( + {"[", CHORDS_CELLS_MIME, + "[json.exception.parse_error.101] parse error at line 1, " + "column 2: syntax error while parsing value - unexpected end " + "of input; expected '[', '{', or a literal"}), + BadPasteRow({"[]", CHORDS_CELLS_MIME, "Nothing to paste!"}), + BadPasteRow({"{\"a\": 1}", CHORDS_CELLS_MIME, + "At of {\"a\":1} - required property 'left_column' " + "not found in object\n"})})); } void Tester::test_bad_note_pastes() { trigger_edit_notes(song_editor_pointer, 1); test_bad_pastes( notes_model_pointer->index(0, 0), - std::vector({BadPasteRow({"", "not a mime", "Cannot paste not a mime into destination needing notes cells"}), - BadPasteRow({"", CHORDS_CELLS_MIME, "Cannot paste chords cells into destination needing notes cells"}), - BadPasteRow({"[", NOTES_CELLS_MIME, "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal"}), - BadPasteRow({"[]", NOTES_CELLS_MIME, "Nothing to paste!"}), - BadPasteRow({"{\"a\": 1}", NOTES_CELLS_MIME, "At of {\"a\":1} - required property 'left_column' not found in object\n"})})); + std::vector( + {BadPasteRow({"", "not a mime", + "Cannot paste not a mime into destination needing " + "notes cells"}), + BadPasteRow({"", CHORDS_CELLS_MIME, + "Cannot paste chords cells into destination needing " + "notes cells"}), + BadPasteRow( + {"[", NOTES_CELLS_MIME, + "[json.exception.parse_error.101] parse error at line 1, " + "column 2: syntax error while parsing value - unexpected end " + "of input; expected '[', '{', or a literal"}), + BadPasteRow({"[]", NOTES_CELLS_MIME, "Nothing to paste!"}), + BadPasteRow({"{\"a\": 1}", NOTES_CELLS_MIME, + "At of {\"a\":1} - required property 'left_column' " + "not found in object\n"})})); undo(song_editor_pointer); } @@ -1061,11 +1085,22 @@ void Tester::test_bad_percussion_pastes() { trigger_edit_percussions(song_editor_pointer, 1); test_bad_pastes( percussions_model_pointer->index(0, 0), - std::vector({BadPasteRow({"", "not a mime", "Cannot paste not a mime into destination needing percussions cells"}), - BadPasteRow({"", CHORDS_CELLS_MIME, "Cannot paste chords cells into destination needing percussions cells"}), - BadPasteRow({"[", PERCUSSIONS_CELLS_MIME, "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing value - unexpected end of input; expected '[', '{', or a literal"}), - BadPasteRow({"[]", PERCUSSIONS_CELLS_MIME, "Nothing to paste!"}), - BadPasteRow({"{\"a\": 1}", PERCUSSIONS_CELLS_MIME, "At of {\"a\":1} - required property 'left_column' not found in object\n"})})); + std::vector( + {BadPasteRow({"", "not a mime", + "Cannot paste not a mime into destination needing " + "percussions cells"}), + BadPasteRow({"", CHORDS_CELLS_MIME, + "Cannot paste chords cells into destination needing " + "percussions cells"}), + BadPasteRow( + {"[", PERCUSSIONS_CELLS_MIME, + "[json.exception.parse_error.101] parse error at line 1, " + "column 2: syntax error while parsing value - unexpected end " + "of input; expected '[', '{', or a literal"}), + BadPasteRow({"[]", PERCUSSIONS_CELLS_MIME, "Nothing to paste!"}), + BadPasteRow({"{\"a\": 1}", PERCUSSIONS_CELLS_MIME, + "At of {\"a\":1} - required property 'left_column' " + "not found in object\n"})})); undo(song_editor_pointer); } @@ -1076,8 +1111,8 @@ void Tester::test_too_loud() { auto *selector_pointer = get_selector_pointer(table_view_pointer); - close_message_later( - "Velocity 378 exceeds 127 for chord 2, note 1. Playing with velocity 127."); + close_message_later("Velocity 378 exceeds 127 for chord 2, note 1. Playing " + "with velocity 127."); selector_pointer->select(notes_model_pointer->index(0, note_interval_column), QItemSelectionModel::Select); @@ -1102,7 +1137,8 @@ void Tester::test_too_many_channels() { auto *selector_pointer = get_selector_pointer(table_view_pointer); - close_message_later("Out of MIDI channels for chord 1, note 17. Not playing note."); + close_message_later( + "Out of MIDI channels for chord 1, note 17. Not playing note."); selector_pointer->select( chords_model_pointer->index(0, chord_interval_column), @@ -1192,7 +1228,10 @@ void Tester::test_export() const { void Tester::test_broken_file() { for (const auto &row : std::vector({ - TwoStringsRow({"{", "[json.exception.parse_error.101] parse error at line 1, column 2: syntax error while parsing object key - unexpected end of input; expected string literal"}), + TwoStringsRow( + {"{", "[json.exception.parse_error.101] parse error at line 1, " + "column 2: syntax error while parsing object key - " + "unexpected end of input; expected string literal"}), TwoStringsRow({"[]", "At of [] - unexpected instance type\n"}), TwoStringsRow({"[1]", "At of [1] - unexpected instance type\n"}), })) { diff --git a/tests/Tester.h b/tests/Tester.h index 4f3b833a..3ec56284 100644 --- a/tests/Tester.h +++ b/tests/Tester.h @@ -44,6 +44,8 @@ private slots: void test_notes_count() const; void test_percussions_count() const; + void test_back_to_chords() const; + void test_number_of_chord_columns() const; void test_number_of_note_columns() const; void test_number_of_percussion_columns() const; @@ -63,6 +65,7 @@ private slots: void test_percussion_flags() const; void test_chord_frequencies() const; + void test_note_frequencies() const; void test_get_unsupported_chord_role() const; void test_get_unsupported_note_role() const;