// Assignment 2 20T1 COMP1511: CS bEats // test_beats.c // // This program was written by YOUR-NAME-HERE (z5555555) // on INSERT-DATE-HERE // // Version 1.0.0: Assignment released. #include #include #include "beats.h" #include "test_beats.h" // Test function for `add_note_to_beat` int test_add_note_to_beat(void) { // Test 1: Rejecting negative inputs. Beat test_beat = create_beat(); if (add_note_to_beat(test_beat, -1, -1) != INVALID_OCTAVE) { return DOES_NOT_MEET_SPEC; } if (add_note_to_beat(test_beat, -1, 0) != INVALID_OCTAVE) { return DOES_NOT_MEET_SPEC; } if (add_note_to_beat(test_beat, 1, -1) != INVALID_KEY) { return DOES_NOT_MEET_SPEC; } // Test 2: Rejecting invalid pitch notes. if (add_note_to_beat(test_beat, 1, 1) != VALID_NOTE) { return DOES_NOT_MEET_SPEC; } if (add_note_to_beat(test_beat, 1, 0) != NOT_HIGHEST_NOTE) { return DOES_NOT_MEET_SPEC; } // Test 3: Accepting valid inputs. if (add_note_to_beat(test_beat, 1, 2) != VALID_NOTE) { return DOES_NOT_MEET_SPEC; } return MEETS_SPEC; } // Test function for `count_notes_in_octave` this is broken int test_count_notes_in_octave(void) { // Test 1: Counting invalid octaves. Beat test_beat = create_beat(); add_note_to_beat(test_beat, 1, 1); if (count_notes_in_octave(test_beat, -1) != 0) { return DOES_NOT_MEET_SPEC; } if (count_notes_in_octave(test_beat, 11) != 0) { return DOES_NOT_MEET_SPEC; } // Test 2: Counting valid octaves. if (count_notes_in_octave(test_beat, 1) != 1) { return DOES_NOT_MEET_SPEC; } if (count_notes_in_octave(test_beat, 1) == 0) { return DOES_NOT_MEET_SPEC; } // Test 3: Counting without any notes struct beat *empty_beat = create_beat(); if (count_notes_in_octave(empty_beat, 0) != 0) { return DOES_NOT_MEET_SPEC; } // Test 4: Counting the correct amount add_note_to_beat(test_beat, 2, 1); add_note_to_beat(test_beat, 2, 2); if (count_notes_in_octave(test_beat, 2) != 2) { return DOES_NOT_MEET_SPEC; } add_note_to_beat(test_beat, 2, 3); if (count_notes_in_octave(test_beat, 2) != 3) { return DOES_NOT_MEET_SPEC; } return MEETS_SPEC; } // These struct definitions are required for the following tests. // They access the fields directly instead of using other functions as tests, // which could be considered unsafe as they are not guaranteed to be correct. // We only want to test a single function, not other functions indirectly. struct track { struct beat *head; struct beat *cur; }; struct beat { struct note *notes; struct beat *next; }; // Test function for `add_beat_to_track` int test_add_beat_to_track(void) { // Test 1: Test if the beat gets added correctly. struct track *test_track = create_track(); struct beat *test_beat = create_beat(); add_beat_to_track(test_track, test_beat); if (test_track->head == NULL) { return DOES_NOT_MEET_SPEC; } // Test 2: Ensure the beat is a shallow copy. if (test_track->head != test_beat) { return DOES_NOT_MEET_SPEC; } // Test 3: Test if the expected fields are NULL. if (test_track->cur != NULL) { return DOES_NOT_MEET_SPEC; } if (test_track->head->notes != NULL) { return DOES_NOT_MEET_SPEC; } // Test 4: Ensure adding muliple beats works correctly. struct beat *test_beat2 = create_beat(); add_beat_to_track(test_track, test_beat2); if (test_track->head != test_beat2) { return DOES_NOT_MEET_SPEC; } // Test 5: Ensure the last field is still NULL. if (test_track->head->next->next != NULL) { return DOES_NOT_MEET_SPEC; } return MEETS_SPEC; } // Test function for `remove_selected_beat` int test_remove_selected_beat(void) { // Test 1: Ensure the correct return type on a track with no selected beat. struct track *test_track = create_track(); struct beat *test_beat = create_beat(); add_beat_to_track(test_track, test_beat); if (remove_selected_beat(test_track) != TRACK_STOPPED) { return DOES_NOT_MEET_SPEC; } // Test 2: Ensure that no beat has been deleted after the previous test. if (test_track->head == NULL) { return DOES_NOT_MEET_SPEC; } // Test 3: Ensure the track is still playing after the attempted removal. if (test_track->cur != NULL) { return DOES_NOT_MEET_SPEC; } // Test 4: Ensure the correct return type on a track with a selected beat. select_next_beat(test_track); if (remove_selected_beat(test_track) != TRACK_STOPPED) { return DOES_NOT_MEET_SPEC; } // Test 5: Ensure the beat has been deleted correct after the previous test. if (test_track->head != NULL) { return DOES_NOT_MEET_SPEC; } // Test 6: Ensure the track is not playing after beat removal. if (test_track->cur != NULL) { return DOES_NOT_MEET_SPEC; } return MEETS_SPEC; } // Another struct definition which is required for testing below. // This can probably be considered bad practice as struct defintions should not // be simply copied across multiple files, but compared to the alternative // of invoking potentially broken functions, this is preferable. struct note { int oct; int key; struct note *next; }; // Test function for `add_musical_note_to_beat` int test_add_musical_note_to_beat(void) { // Test 1: Ensure the beat is added to an empty beat. struct beat *test_beat = create_beat(); add_musical_note_to_beat(test_beat, "2C#"); if (test_beat->notes == NULL) { return DOES_NOT_MEET_SPEC; } // Test 2: Ensure the beat has the correct pitch. if (test_beat->notes->oct != 2 || test_beat->notes->key != 4) { return DOES_NOT_MEET_SPEC; } // Test 3: Ensure a higher beat is added when appropriate. add_musical_note_to_beat(test_beat, "2C##"); if (test_beat->notes->next == NULL) { return DOES_NOT_MEET_SPEC; } // Test 4: Ensure that a lower beat is added when appropriate. add_musical_note_to_beat(test_beat, "2C"); if (test_beat->notes->oct != 2 || test_beat->notes->key != 3) { return DOES_NOT_MEET_SPEC; } return MEETS_SPEC; }