# Tokens - White Box Exercise ###### tags: `etsiinf` ### Specifying test cases | Id | TC1 | | --------------- | -------------------------------------------------------------------------------------------------------- | | Goal | Test the count of alphanumeric tokens using an empty imput | | Context | The user may run the program without any input, a return message could be returned, or a specified error | | Inputs | run with `./tokens` | | Expected output | No output. | | Observed output | Runtime Exception | | Failure | Runtime Exception | | Id | TC2 | | --------------- | --------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of alphanumeric tokens | | Context | This is the simplest way of running the program, without any flags and checking the count of the provided words | | Inputs | Value = `word sentence char` run with `./tokens` | | Expected output | `1 word 1 sentence 1 char` | | Observed output | `1 word 1 sentence 1 char` | | Failure | No | | Id | TC3 | | --------------- | ------------------------------------------------------------------------ | | Goal | Test the count of repeated alphanumeric tokens | | Context | Verifying if the count of repeated words is correct, when using no flags | | Inputs | Value = `word word char` run with `./tokens` | | Expected output | `2 word 1 char` | | Observed output | `2 word 1 char` | | Failure | No | | Id | TC4 | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of alphanumeric tokens using only tokens with numbers using the `-i` flag | | Context | Providing to the system uppercase and lowercase letters, and then using the -i flag to see if the program converts them all to lowercase | | Inputs | Value = `Word word ChAr` run with `./tokens -i` | | Expected output | `2 word 1 char` | | Observed output | `2 word 1 char` | | Failure | No | | Id | TC5 | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of only numeric tokens | | Context | Verifying if the count of numbers is correct, when using no flags. Since there are no flags present this should be no different than regular words | | Inputs | Value = `123 456 789` run with `./tokens` | | Expected output | `1 123 1 456 1 789` | | Observed output | `1 123 1 456 1 789` | | Failure | No | | Id | TC6 | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of only numeric tokens using the `-a` flag | | Context | Verifying if the count of numbers is correct, using the `-a` for only alphanumeric characters. Since we are only providing numbers, these sould be ignored | | Inputs | Value = `123 456 789` run with `./tokens -a` | | Expected output | Empty | | Observed output | `1 123 1 456 1 789` | | Failure | No | | Id | TC7 | | --------------- | --------------------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of alphanumeric using the `-m` flag to check if only the tokens with the specified minimum count are printed | | Context | When providing the `-m <value>` flag the tokens with a count higher or equal to value should be present | | Inputs | Value = `word word word new new char` run with `./tokens -m 2` | | Expected output | `3 word 2 new` | | Observed output | `3 word` | | Failure | No | | Id | TC8 | | --------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of tokens with the special character `&` using the `-c` flag | | Context | Veryfing if the system prints any output when the input contains the special character `&` a special character that is error prone. | | Inputs | Value = `&& & ola` run with `./tokens -c &` | | Expected output | `1 && 1 & 1 ola` | | Observed output | No output | | Failure | No | | Id | TC9 | | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Goal | Test the count of tokens with tokens with special characters using the `-c` flag | | Context | Veryfing if the system prints any output when the input contains special characters (most common ones), and using the -c flag (which allows chars to be part of tokens). | | Inputs | Value = `ola! ola!#` run with `./tokens -c !#` | | Expected output | `1 ola! 1 ola!#` | | Observed output | `1 ola! 1 ola!#` | | Failure | No | | Id | TC10 | | --------------- | ------------------------------------------------------------------------------------------------------------- | | Goal | Test the count of repeated tokens with tokens with special characters using the `-c` flag | | Context | Check if the system prints any output when the input is only made of special characters, using the -c as flag | | Inputs | Value = `!# !#? !# !#?` run with `./tokens -c !#?` | | Expected output | `2 !# 2 !#?` | | Observed output | `2 !# 2 !#?` | | Failure | No | ### Decision coverage table | | L22 | L25 | L35 | L36 | L47 | L49 | L63 | L64 | L67 | L68 | L72 | L87 | L88 | L98 | L101 | L102 | L103 | L109 | L110 | L113 | L121 | L122 | L124 | | ------------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | | **TC1** | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | | **TC2** | T/F | T | T/F | T | T | - | T/F | T/F | T/F | F | T/F | F | - | - | - | - | - | F | F | T | | **TC3** | T/F | T | T/F | T | T | T | T/F | T/F | T/F | F | T/F | F | - | - | - | - | - | F | F | T | | **TC4** | T/F | T | T/F | T | - | T | T/F | T/F | T/F | - | T/F | T/F | F | F | - | T | F | F | F | T | | **TC5** | T/F | T | T/F | T | T | - | T/F | T/F | T/F | F | T/F | F | - | - | - | - | - | F | F | T | | **TC6** | T/F | T | T/F | T | T | - | T/F | T/F | T/F | F | T/F | T/F | T | F | - | F | F | F | T | T | | **TC7** | T/F | T/F | T/F | T | T | T | T/F | T/F | T/F | F | T/F | T/F | F | F | - | F | T | F | F | T | | **TC8** | - | - | - | - | - | - | - | - | - | - | - | T/F | - | - | - | - | - | T | - | - | | **TC9** | T/F | T | T/F | T | F | F | T/F | T/F | T/F | F | T/F | T/F | F | T | T/F | F | F | F | F | T | | **TC10** | T/F | T | T/F | T | F | F | T/F | T/F | T/F | F | T/F | T/F | F | T | T/F | F | F | F | F | T | | **Coverage** | T/F | T/F | T/F | T | T/F | T/F | T/F | T/F | T/F | F | T/F | T/F | T/F | T/F | T/F | T/F | T/F | T/F | T/F | T | ### Findings - When flag `-a` is set, the variable `Alpha` is still set to false. This means that this feature will never work. This causes `L122` on the coverage table to never have the `false` value. - When using the flag `-m` which indicates the minimum count needeed for the entry to be printed, we considered this should be inclusive, meaning that `-m 2` entries with a count of 2 should be printed. This could be just a wording problem in the `Specification for program "tokens"` - Conditions in `L38` and `L73` could not be verified for both scenarios. This could be due to a lack of understanding of how the `-c characters` use works, which could have a more detailed explanation in the `Specification for program "tokens"` ```c /*COPYRIGHT (c) Copyright 1992 Gary Perlman */ #include <stdio.h> #include <string.h> #include <assert.h> int Ignore = 0; int Mincount = 0; int Alpha = 0; char MapAllowed[256]; typedef struct tnode { char *contents; int count; struct tnode *left; struct tnode *right; } TNODE; void treeprint(tree) TNODE *tree; // print the tree { if (tree != NULL) { printf("passed L22 if\n"); treeprint(tree->left); if (tree->count > Mincount) { printf("%7d\t%s\n", tree->count, tree->contents); printf("passed L25 if\n"); } else printf("didnt passed L25 if\n"); treeprint(tree->right); } else printf("didnt passed L22 if\n"); } TNODE * install(string, tree) char *string; TNODE *tree; { int cond; assert(string != NULL); if (tree == NULL) { printf("passed L36 if\n"); if (tree = (TNODE *)calloc(1, sizeof(TNODE))) { printf("passed L38 if\n"); tree->contents = strdup(string); tree->count = 1; } else { printf("didnt passed L38 if\n"); } } else { printf("didnt passed L36 if\n"); cond = strcmp(string, tree->contents); if (cond < 0) { printf("passed L47 if\n"); tree->left = install(string, tree->left); } else if (cond == 0) { printf("passed L49 if\n"); tree->count++; } else { printf("didnt passed L47 and L49 if\n"); tree->right = install(string, tree->right); } } return (tree); } char * getword(ioptr) FILE *ioptr; { static char string[1024]; char *ptr = string; register int c; assert(ioptr != NULL); for (;;) { c = getc(ioptr); if (c == EOF) { printf("passed L67 if\n"); if (ptr == string) { printf("passed L68 if\n"); return (NULL); } else { printf("didnt passed L68 if\n"); break; } } else printf("didnt passed L67 if\n"); if (!MapAllowed[c]) { printf("passed L72 if\n"); if (ptr == string) { printf("passed L73 if\n"); continue; } else { printf("didnt passed L73 if\n"); break; } } else printf("didnt passed L72 if\n"); *ptr++ = MapAllowed[c]; } *ptr = '\0'; return (string); } void tokens(ioptr) FILE *ioptr; { TNODE *root = NULL; char *s; assert(ioptr != NULL); while (s = getword(ioptr)) { printf("passed L88 while\n"); root = install(s, root); } printf("got out of L88 while\n"); treeprint(root); } int main(argc, argv) int argc; char **argv; { int c, errcnt = 0; extern char *optarg; while ((c = getopt(argc, argv, "ac:im:")) != EOF) { printf("passed L98 while\n"); switch (c) { case 'a': printf("passed L101 switch\n"); Alpha = 0; break; case 'c': printf("passed L102 switch\n"); while (*optarg) { printf("passed L103 while\n"); MapAllowed[*optarg] = *optarg; optarg++; } printf("got out of L103 while\n"); break; case 'i': printf("passed L109 switch\n"); Ignore = 1; break; case 'm': printf("passed L110 switch\n"); Mincount = atoi(optarg); break; default: errcnt++; } } printf("got out of L98 while\n"); if (errcnt) { printf("passed L113 if\n"); fprintf(stderr, "Usage: %s [-i] [-c chars] [-m count]\n", *argv); return (1); } else { printf("didnt passed L113 if\n"); } for (c = 'a'; c <= 'z'; c++) MapAllowed[c] = c; for (c = 'A'; c <= 'Z'; c++) MapAllowed[c] = Ignore ? c - 'A' + 'a' : c; if (!Alpha) { printf("passed L123 if\n"); for (c = '0'; c <= '9'; c++) MapAllowed[c] = c; } else { printf("didnt passed L123 if\n"); } tokens(stdin); return (0); } ```