diff options
| author | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2025-02-13 18:00:17 +1100 |
|---|---|---|
| committer | Nicolas James <Eele1Ephe7uZahRie@tutanota.com> | 2025-02-13 18:00:17 +1100 |
| commit | 98cef5e9a772602d42acfcf233838c760424db9a (patch) | |
| tree | 5277fa1d7cc0a69a0f166fcbf10fd320f345f049 /comp1511/cs_beats/test_beats.c | |
initial commit
Diffstat (limited to 'comp1511/cs_beats/test_beats.c')
| -rw-r--r-- | comp1511/cs_beats/test_beats.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/comp1511/cs_beats/test_beats.c b/comp1511/cs_beats/test_beats.c new file mode 100644 index 0000000..d1eb793 --- /dev/null +++ b/comp1511/cs_beats/test_beats.c @@ -0,0 +1,190 @@ +// 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 <stdio.h> +#include <stdlib.h> + +#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; +} |
