38     static void help_TestFilename(
const char * filename) {
 
   39         char letter = CNT & 0x7F; 
 
   41         sut.
Open(filename, 
'w');
 
   43         sut.
Open(filename, 
'r');
 
   44         TEST_ASSERT_EQUAL_INT(letter, sut.
Get());
 
   45         TEST_ASSERT_EQUAL_INT(-1, sut.
Get());
 
   48     static int help_DeleteAllFiles(
void) {
 
   49         const int MAXIMUM_FILE_COUNT = 1000;
 
   51         for (count = 0; count < MAXIMUM_FILE_COUNT; count++) {
 
   55             if (sut.
NextFile(filename) != 
true) {
 
   58             sut.
Open(filename, 
'd');
 
   63     static void cog_DoNothing(
void * arg) {
 
   64         waitcnt(CLKFREQ * 50 + CNT);
 
   67     static int help_CountNumberOfFreeCogs(
void) {
 
   68         const int stacksize = 
sizeof (_thread_state_t) + 
sizeof (
int) * 10;
 
   69         int * cog_stack = (
int*) malloc(stacksize);
 
   70         int cog_id = cogstart(cog_DoNothing, NULL, cog_stack, stacksize);
 
   75             free_cogs = help_CountNumberOfFreeCogs() + 1;
 
   84     static void setUp(
void) {
 
   89     static void tearDown(
void) {
 
   90         help_DeleteAllFiles();
 
   98     static void test_Mount(
void) {
 
  103     static void test_MountMultiple(
void) {
 
  111     static void test_MultipleUnmounts(
void) {
 
  113         TEST_ASSERT_EQUAL_INT(0, sut.
GetError());
 
  115         TEST_ASSERT_EQUAL_INT(0, sut.
GetError());
 
  118     static void test_MountNoSd(
void) {
 
  123     static void test_UnmountFreesCog(
void) {
 
  124         int cogsFreeBefore = help_CountNumberOfFreeCogs();
 
  126         TEST_ASSERT_EQUAL_INT(cogsFreeBefore + 1, help_CountNumberOfFreeCogs());
 
  129     static void test_DestructorFreesCog(
void) {
 
  131         int cogsFreeBefore = help_CountNumberOfFreeCogs();
 
  135             TEST_ASSERT_EQUAL_INT(cogsFreeBefore - 1, help_CountNumberOfFreeCogs());
 
  137         TEST_ASSERT_EQUAL_INT(cogsFreeBefore, help_CountNumberOfFreeCogs());
 
  144     static void test_OpenExistingFileForWrite(
void) {
 
  145         sut.
Open(
"RANDOM.RND", 
'w');
 
  147         sut.
Open(
"RANDOM.RND", 
'w');
 
  149         sut.
Open(
"RANDOM.RND", 
'r');
 
  150         TEST_ASSERT_EQUAL_INT(
'b', sut.
Get());
 
  154     static void test_OpenNonexistentFileForRead(
void) {
 
  155         sut.
Open(
"RANDOM.RND", 
'r');
 
  159     static void test_OpenNonexistentFileForWrite(
void) {
 
  160         sut.
Open(
"RANDOM.RND", 
'w');
 
  164     static void test_OpenForDeleteNonexistentFile(
void) {
 
  165         sut.
Open(
"RANDOM.RND", 
'd');
 
  169     static void test_OpenForAppendNonexistentFile(
void) {
 
  170         sut.
Open(
"RANDOM.RND", 
'a');
 
  174     static void test_OpenTooLongFilename(
void) {
 
  175         sut.
Open(
"REALLONGNAME.RND", 
'w');
 
  179     static void test_CloseFileTwice(
void) {
 
  186     static void test_OpenSpecialCharacterFilenames(
void) {
 
  187         help_TestFilename(
"$%-_@~`!.(){");
 
  188         help_TestFilename(
"}^#& ");
 
  191     static void test_OpenFilenameWithExtensionOnly(
void) {
 
  192         help_TestFilename(
".WAT");
 
  195     static void test_OpenFilenameWithoutExtension(
void) {
 
  196         help_TestFilename(
"Hello");
 
  199     static void test_OpenShorterFilenameThan8dot3(
void) {
 
  200         help_TestFilename(
"a.a");
 
  203     static void test_OpenEmptyFilename(
void) {
 
  204         help_TestFilename(
"");
 
  243     static void test_PutChar(
void) {
 
  244         sut.
Open(
"RANDOM.RND", 
'w');
 
  245         TEST_ASSERT_EQUAL_INT(0, sut.
Put(
'a'));
 
  248     static void test_GetCharFromExistingFile(
void) {
 
  249         sut.
Open(
"RANDOM.RND", 
'd');
 
  250         sut.
Open(
"RANDOM.RND", 
'w');
 
  252         sut.
Open(
"RANDOM.RND", 
'r');
 
  253         TEST_ASSERT_EQUAL_INT(
'x', sut.
Get());
 
  256     static void test_GetCharAfterEndOfFile(
void) {
 
  257         sut.
Open(
"RANDOM.RND", 
'd');
 
  258         sut.
Open(
"RANDOM.RND", 
'w');
 
  260         sut.
Open(
"RANDOM.RND", 
'r');
 
  262         TEST_ASSERT_EQUAL_INT(-1, sut.
Get());
 
  265     static void test_PutCharAppend(
void) {
 
  266         sut.
Open(
"APPEND.TXT", 
'a');
 
  267         TEST_ASSERT_EQUAL_INT(0, sut.
Put(
'-'));
 
  268         sut.
Open(
"APPEND.TXT", 
'r');
 
  269         TEST_ASSERT_EQUAL_INT(
'-', sut.
Get());
 
  270         TEST_ASSERT_EQUAL_INT(-1, sut.
Get());
 
  273     static void test_Put(
void) {
 
  274         sut.
Open(
"RANDOM.RND", 
'w');
 
  275         TEST_ASSERT_EQUAL_INT(5, sut.
Put(
"Hello"));
 
  276         sut.
Open(
"RANDOM.RND", 
'r');
 
  277         TEST_ASSERT_EQUAL_INT(
'H', sut.
Get());
 
  278         TEST_ASSERT_EQUAL_INT(
'e', sut.
Get());
 
  279         TEST_ASSERT_EQUAL_INT(
'l', sut.
Get());
 
  280         TEST_ASSERT_EQUAL_INT(
'l', sut.
Get());
 
  281         TEST_ASSERT_EQUAL_INT(
'o', sut.
Get());
 
  282         TEST_ASSERT_EQUAL_INT(-1, sut.
Get());
 
  285     static void test_PutSEmptyString(
void) {
 
  286         sut.
Open(
"RANDOM.RND", 
'w');
 
  287         TEST_ASSERT_EQUAL_INT(0, sut.
Put(
""));
 
  290     static void test_Get(
void) {
 
  291         sut.
Open(
"RANDOM.RND", 
'w');
 
  292         sut.
Put(
"World\0ABC", 6);
 
  295         sut.
Open(
"RANDOM.RND", 
'r');
 
  296         TEST_ASSERT_EQUAL_INT(6, sut.
Get(buffer, 6));
 
  297         TEST_ASSERT_EQUAL_STRING(
"World", buffer);
 
  300     static void test_GetBufferPastEndOfFile(
void) {
 
  301         sut.
Open(
"RANDOM.RND", 
'w');
 
  302         sut.
Put(
"World\0", 6);
 
  305         sut.
Open(
"RANDOM.RND", 
'r');
 
  306         TEST_ASSERT_EQUAL_INT(6, sut.
Get(buffer, 10));
 
  307         TEST_ASSERT_EQUAL_STRING(
"World", buffer);
 
  310     static void test_WriteLargeFile(
void) {
 
  311         sut.
Open(
"RANDOM.RND", 
'w');
 
  313         const int kAlphabetCount = 2048;
 
  315         for (
int i = 0; i < kAlphabetCount; i++) {
 
  316             for (
int letter = 
'a'; letter <= 
'z'; letter++) {
 
  317                 TEST_ASSERT_EQUAL_INT(0, sut.
Put(letter));
 
  321         sut.
Open(
"RANDOM.RND", 
'r');
 
  322         for (
int i = 0; i < kAlphabetCount; i++) {
 
  323             for (
int letter = 
'a'; letter <= 
'z'; letter++) {
 
  324                 TEST_ASSERT_EQUAL_INT(letter, sut.
Get());
 
  328         TEST_ASSERT_EQUAL_INT(-1, sut.
Get());
 
  336     static void test_SetDate(
void) {
 
  342         int time = 0b0001101111011101;
 
  346         int date = 0b0010100000100010;
 
  348         int datetime = (date << 16) + time;
 
  350         TEST_ASSERT_BITS(0xFFFFFFFF, datetime, sut.
SetDate(2000, 1, 2, 3, 30, 58));
 
  353     static void test_SeekSmallFile(
void) {
 
  354         sut.
Open(
"RANDOM.RND", 
'w');
 
  355         sut.
Put(
"Hello World!");
 
  356         sut.
Open(
"RANDOM.RND", 
'r');
 
  358         for (
int i = 0; i < 5; i++)
 
  361         TEST_ASSERT_EQUAL_INT(0, sut.
Seek(2));
 
  362         TEST_ASSERT_EQUAL_INT(
'l', sut.
Get());
 
  365     static void test_SeekOnWriteAfterOpening(
void) {
 
  366         sut.
Open(
"RANDOM.RND", 
'w');
 
  367         TEST_ASSERT_EQUAL_INT(-1, sut.
Seek(0));
 
  370     static void test_SeekOnWriteAfterWriting(
void) {
 
  371         sut.
Open(
"RANDOM.RND", 
'w');
 
  372         sut.
Put(
"Hello World!");
 
  373         TEST_ASSERT_EQUAL_INT(-1, sut.
Seek(0));
 
  376     static void test_SeekOnWriteAndCanStillWriteAfter(
void) {
 
  377         sut.
Open(
"RANDOM.RND", 
'w');
 
  381         sut.
Open(
"RANDOM.RND", 
'r');
 
  382         for (
int i = 0; i < 5; i++)
 
  384         TEST_ASSERT_EQUAL_INT(
'W', sut.
Get());
 
  387     static void test_SeekOnRead(
void) {
 
  388         sut.
Open(
"RANDOM.RND", 
'w');
 
  389         sut.
Put(
"Hello World");
 
  390         sut.
Open(
"RANDOM.RND", 
'r');
 
  392         TEST_ASSERT_EQUAL_INT(
'W', sut.
Get());
 
  395     static void test_SeekOnLargeFile(
void) {
 
  400         sut.
Open(
"RANDOM.RND", 
'w');
 
  402         for (
int i = 0; i < 3072; i++)
 
  403             for (
char testchar = 
'a'; testchar <= 
'p'; testchar++)
 
  406         sut.
Open(
"RANDOM.RND", 
'r');
 
  409         TEST_ASSERT_EQUAL_INT(0, sut.
Seek(0));
 
  410         TEST_ASSERT_EQUAL_INT(
'a', sut.
Get());
 
  413         TEST_ASSERT_EQUAL_INT(0, sut.
Seek(16 * 1024 + 3));
 
  414         TEST_ASSERT_EQUAL_INT(
'd', sut.
Get());
 
  417         TEST_ASSERT_EQUAL_INT(0, sut.
Seek(40 * 1024 + 8));
 
  418         TEST_ASSERT_EQUAL_INT(
'i', sut.
Get());
 
  421     static void test_GetClusterSize(
void) {
 
  422         TEST_ASSERT_EQUAL_INT_MESSAGE(32768, sut.
GetClusterSize(), 
"SD card should be formatted in 32K clusters.");
 
  425     static void test_getNextFileFindsAllFiles(
void) {
 
  427         const int MAXIMUM_FILE_COUNT = 100;
 
  429         for (count = 0; count < MAXIMUM_FILE_COUNT; count++) {
 
  433             if (sut.
NextFile(filename) != 
true) {
 
  436             sut.
Open(filename, 
'd');
 
  439         TEST_ASSERT_TRUE(count != MAXIMUM_FILE_COUNT);
 
  443     static void test_getNextFileFindsCorrectFiles(
void) {
 
  446         const int FILECOUNT = 3;
 
  449         const char * filenames[FILECOUNT];
 
  450         filenames[0] = 
"NEXTA.TXT";
 
  451         filenames[1] = 
"NEXTB.TXT";
 
  452         filenames[2] = 
"NEXTC.TXT";
 
  454         bool filenameFound[FILECOUNT];
 
  455         for (
int filenameFoundI = 0; filenameFoundI < FILECOUNT; filenameFoundI++) {
 
  456             filenameFound[filenameFoundI] = 
false;
 
  460         sut.
Open(filenames[0], 
'w');
 
  463         sut.
Open(filenames[1], 
'w');
 
  466         sut.
Open(filenames[2], 
'w');
 
  471         char nextFilename[13];
 
  472         while (sut.
NextFile(nextFilename) == 
true) {
 
  474             for (i = 0; i < FILECOUNT; i++) {
 
  475                 if (strcmp(filenames[i], nextFilename) == 0) {
 
  476                     TEST_ASSERT_FALSE_MESSAGE(filenameFound[i], 
"Should not already be found.");
 
  477                     filenameFound[i] = 
true;
 
  481             TEST_ASSERT_TRUE_MESSAGE(i != FILECOUNT, 
"Unmatched filename!");
 
  484         for (
int i = 0; i < FILECOUNT; i++) {
 
  485             TEST_ASSERT_TRUE(filenameFound[i]);
 
  489     static void test_OpenRootDirMultipleTimesInARowReturnsAllFilesEveryTime(
void) {
 
  490         const int FILECOUNT = 3;
 
  493         const char * filenames[FILECOUNT];
 
  494         filenames[0] = 
"NEXTA.TXT";
 
  495         filenames[1] = 
"NEXTB.TXT";
 
  496         filenames[2] = 
"NEXTC.TXT";
 
  498         bool filenameFound[FILECOUNT];
 
  500         sut.
Open(filenames[0], 
'w');
 
  503         sut.
Open(filenames[1], 
'w');
 
  506         sut.
Open(filenames[2], 
'w');
 
  510         for (
int iterationsThroughRoot = 0; iterationsThroughRoot < 5; iterationsThroughRoot++) {
 
  513             for (
int filenameFoundI = 0; filenameFoundI < FILECOUNT; filenameFoundI++) {
 
  514                 filenameFound[filenameFoundI] = 
false;
 
  519             char nextFilename[13];
 
  520             while (sut.
NextFile(nextFilename) == 
true) {
 
  522                 for (i = 0; i < FILECOUNT; i++) {
 
  523                     if (strcmp(filenames[i], nextFilename) == 0) {
 
  524                         TEST_ASSERT_FALSE_MESSAGE(filenameFound[i], 
"Should not already be found.");
 
  525                         filenameFound[i] = 
true;
 
  529                 TEST_ASSERT_TRUE_MESSAGE(i != FILECOUNT, 
"Unmatched filename!");
 
  532             for (
int i = 0; i < FILECOUNT; i++) {
 
  533                 TEST_ASSERT_TRUE(filenameFound[i]);
 
  538     static void test_GetFilesizeSmall(
void) {
 
  539         const char filename[] = 
"FILESIZE.TXT";
 
  540         const char content[] = 
"Hello";
 
  541         sut.
Open(filename, 
'w');
 
  544         sut.
Open(filename, 
'r');
 
  545         TEST_ASSERT_EQUAL_INT(strlen(content), sut.
GetFilesize());
 
  549     static void test_GetFilesizeNothing(
void) {
 
  550         const char filename[] = 
"EMPTY.TXT";
 
  551         sut.
Open(filename, 
'w');
 
  553         sut.
Open(filename, 
'r');
 
  558     static void test_GetFilesizeLotsOfContent(
void) {
 
  559         const char filename[] = 
"LARGE.TXT";
 
  560         sut.
Open(filename, 
'w');
 
  562         const int kByteCount = 1024 * 128;
 
  564         for (
int i = 0; i < kByteCount; i++) {
 
  570         sut.
Open(filename, 
'r');
 
  572         TEST_ASSERT_EQUAL_INT(kByteCount, sut.
GetFilesize());
 
  577     static void test_GetFilesizeAfterReadingSome(
void) {
 
  578         const char filename[] = 
"AFTER.TXT";
 
  579         const char content[] = 
"Some text to take up space";
 
  580         sut.
Open(filename, 
'w');
 
  583         sut.
Open(filename, 
'r');
 
  584         for (
int i = 0; i < 5; i++) {
 
  587         TEST_ASSERT_EQUAL_INT(strlen(content), sut.
GetFilesize());
 
  590     static void test_GetFilesizeAfterReadingPastEndOfFile(
void) {
 
  591         const char filename[] = 
"AFTER.TXT";
 
  592         const char content[] = 
"Some text to take up space";
 
  593         sut.
Open(filename, 
'w');
 
  596         sut.
Open(filename, 
'r');
 
  597         while (sut.
Get() != -1) {
 
  600         TEST_ASSERT_EQUAL_INT(strlen(content), sut.
GetFilesize());