Exemplo n.º 1
0
static void test9() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  _check_err(KeyVal_setValue(kv, "k1", "k3"), "KeyVal_setValue");            // sets k1 to k3
  _check_err(KeyVal_setValue(kv, "k2::k3", "${k1}"), "KeyVal_setValue");     // sets k2::k3 to "k3"
  _check_err(KeyVal_setValue(kv, "k4", "${k2::${k1}}"), "KeyVal_setValue");  // sets k4 to "k3"

  // baseline writing:
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output("`k1` = `k3`\n`k2::k3` = `${k1}`\n`k4` = `${k2::${k1}}`\n") == 0, "9a. saving with interp=0, align=0");

  // writing with just interp:
  _check_err(KeyVal_save(kv, OUT, 1, 0), "KeyVal_save");
  ok(_check_output("`k1` = `k3`\n`k2::k3` = `k3`\n`k4` = `k3`\n") == 0, "9b. saving with interp=1, align=0");

  // writing with just align:
  _check_err(KeyVal_save(kv, OUT, 0, 1), "KeyVal_save");
  ok(_check_output("`k1`     = `k3`\n`k2::k3` = `${k1}`\n`k4`     = `${k2::${k1}}`\n") == 0, "9c. saving with interp=0, align=1");

  // writing with both interp and align:
  _check_err(KeyVal_save(kv, OUT, 1, 1), "KeyVal_save");
  ok(_check_output("`k1`     = `k3`\n`k2::k3` = `k3`\n`k4`     = `k3`\n") == 0, "9d. saving with interp=1, align=1");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 2
0
int main(int ac, char* av[])
{
  GError* err = NULL;
  char* uri = ac == 2 ? av[1] : "https://localhost:4444/RPC2";

  xr_debug_enabled = XR_DEBUG_CALL;

  xr_client_conn* conn = xr_client_new(&err);
  if (_check_err(&err))
    goto err;

  xr_client_open(conn, uri, &err);
  if (_check_err(&err))
    goto err;

  // start job

  gint job_id = TTest2_startQuery(conn, "http://localhost/slow.php", &err);
  if (_check_err(&err))
    goto err;

  // poll job result

  while (TRUE)
  {
    TQueryResult* result =  TTest2_completeQuery(conn, job_id, &err);
    if (err && err->code != T_XMLRPC_ERROR_TEST2_AGAIN)
    {
      _check_err(&err);
      goto err;
    }

    if (result)
    {
      g_print("Job done, result:\n%s\n", result->response);
      TQueryResult_free(result);
      break;
    }
    else
      g_usleep(1000 * 1000);

    g_clear_error(&err);
  }

  xr_client_free(conn);
  xr_fini();
  return 0;

err:
  xr_client_free(conn);
  xr_fini();
  return 1;
}
Exemplo n.º 3
0
static void
test1() {
  
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // 1a: missing file
  remove(IN);
  _check_load_return(kv, 2, "1a. detects missing input file");

  // 1b: file with complete crap in it
  _set_input("this file has complete crap in it\n");
  _check_load_return(kv, 1, "1b. detects complete crap");

  // 1c: file with EOF in key
  _set_input("`key");
  _check_load_return(kv, 1, "1c. detects EOF in key");

  // 1d/1e: file with missing "=" or "remove"
  _set_input("`key`\n");
  _check_load_return(kv, 1, "1d. detects '\\n' instead of '=' or 'remove'");
  _set_input("`key`");
  _check_load_return(kv, 1, "1e. detects EOF instead of '=' or 'remove'");

  // 1f: file with "foo" instead of "=" or "remove"
  _set_input("`key` foo");
  _check_load_return(kv, 1, "1f. detects crap instead of '=' or 'remove'");

  // 1g/1h: file with missing value
  _set_input("`key` =\n");
  _check_load_return(kv, 1, "1g. detects '\\n' instead of value");
  _set_input("`key` =");
  _check_load_return(kv, 1, "1h. detects EOF instead of value");

  // 1i: file with EOF in value
  _set_input("`key` = `val");
  _check_load_return(kv, 1, "1i. detects EOF in value (missing close-quote)");

  // 1j: file with comment after value (sorry, not allowed!)
  _set_input("`key` = `val` #moo!");
  _check_load_return(kv, 1, "1j. detects comment after value");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 4
0
static void
test5() {

  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // 5a: key and val with escaped quote.  Input should look like this:
  // `\`key\\` = `\\val\``
  // `key\`\`key` = `val\\\\val`
  const char *TEXT = "`\\`key\\\\` = `\\\\val\\``\n`key\\`\\`key` = `val\\\\\\\\val`\n";
  _set_input(TEXT);
  if (!ok(KeyVal_load(kv, IN) == 0, "5a. reads escapes ok")) return;

  // 5b. escapes on the outside of key:
  char *value;
  _check_err(KeyVal_getValue(&value, kv, "`key\\", 0), "KeyVal_getValue");
  if (ok(value != 0, "5b. key with escapes at start and end")) {

    // 5c. escapes on the outsides of value:
    ok(strcmp(value, "\\val`") == 0, "5c. value with escapes at start and end");
  }

  // 5d. (consecutive) escapes in the middle of key:
  _check_err(KeyVal_getValue(&value, kv, "key``key", 0), "KeyVal_getValue");
  if (ok(value != 0, "5d. key with consecutive escapes in middle")) {

    // 5e. (consecutive) escapes in the middle of value:
    ok(strcmp(value, "val\\\\val") == 0, "5e. value with consecutive escapes in middle");
  }

  // 5f. write out this nastiness:
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output(TEXT) == 0, "5f. escapes write out correctly");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 5
0
static void
test2() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // 2a: file with nothing in it
  FILE *fh = fopen(IN, "w");
  fclose(fh);
  _check_load_return(kv, 0, "2a. empty input file");

  // 2b: file with only whitespace
  _set_input("  \t \t  \n\t\t  \n\n ");  // also tests missing \n at EOF
  _check_load_return(kv, 0, "2b. whitespace-only input file");

  // 2c: file with only comments
  _set_input("# nothing\n# at all!\n");
  _check_load_return(kv, 0, "2c. comment-only input file");

  // 2d: save it out; should get nothing
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output("") == 0, "2d. writing out empty input generates empty output");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 6
0
static void test8() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  _check_err(KeyVal_setValue(kv, "k1", "2"), "KeyVal_setValue");
  _check_err(KeyVal_setValue(kv, "k2", "asdf${k1}zxcv"), "KeyVal_setValue");  // in middle
  _check_err(KeyVal_setValue(kv, "k3", "${k1}zxcv"), "KeyVal_setValue");  // at beginning
  _check_err(KeyVal_setValue(kv, "k4", "asdf${k1}"), "KeyVal_setValue");  // at end
  _check_err(KeyVal_setValue(kv, "k5", "a${k1}b${k1}${k1}c"), "KeyVal_setValue");  // multiple values
  _check_err(KeyVal_setValue(kv, "k6", "${k${k1}}"), "KeyVal_setValue");   // embedded variables
  _check_err(KeyVal_setValue(kv, "k7", "}${"), "KeyVal_setValue");   // weird string 1
  _check_err(KeyVal_setValue(kv, "k8", "${}"), "KeyVal_setValue");   // weird string 2
  _check_err(KeyVal_setValue(kv, "k9", "${k10}"), "KeyVal_setValue");   // mutually recursive variables
  _check_err(KeyVal_setValue(kv, "k10", "${k9}"), "KeyVal_setValue");   // mutually recursive variables

  char *value;
  _check_err(KeyVal_getValue(&value, kv, "k2", 1), "KeyVal_getValue");
  if (!ok(strcmp(value, "asdf2zxcv") == 0, "8a. variable in middle of string")) {
    printf(" - got '%s' instead of 'asdf2zxcv'\n", value);
  }
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k3", 1), "KeyVal_getValue");
  ok(strcmp(value, "2zxcv") == 0, "8b. variable at beginning of string");
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k4", 1), "KeyVal_getValue");
  ok(strcmp(value, "asdf2") == 0, "8c. variable at end of string");
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k5", 1), "KeyVal_getValue");
  ok(strcmp(value, "a2b22c") == 0, "8d. multiple variables in the string");
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k6", 1), "KeyVal_getValue");
  ok(strcmp(value, "asdf2zxcv") == 0, "8e. embedded variables");
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k7", 1), "KeyVal_getValue");
  ok(strcmp(value, "}${") == 0, "8f. weird initial closing brace");
  free(value);

  _check_err(KeyVal_getValue(&value, kv, "k8", 1), "KeyVal_getValue");
  ok(strcmp(value, "${}") == 0, "8g. empty variable name");
  free(value);

  unsigned char getvalue_res = KeyVal_getValue(&value, kv, "k9", 1);
  ok(getvalue_res == 2, "8h. recursive variables detected");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 7
0
static void
test7() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // empty arrays:
  unsigned long index;
  _check_err(KeyVal_findIdealIndex(&index, kv, "a"), "KeyVal_findIdealIndex");
  ok(index == 0, "7a. findIdealIndex ok on empty array");
  ok(KeyVal_findIndex(&index, kv, "a") == 2, "7b. findIndex ok on empty array");

  // one element:
  _check_err(KeyVal_setValue(kv, "2", "asdf"), "KeyVal_setValue");
  // searching something that should go in front:
  _check_err(KeyVal_findIdealIndex(&index, kv, "1"), "KeyVal_findIdealIndex");
  ok(index == 0, "7d. findIdealIndex-1 ok on array1");
  ok(KeyVal_findIndex(&index, kv, "1") == 2, "7e. findIndex-1 ok on array1");
  // searching the one thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "2"), "KeyVal_findIdealIndex");
  ok(index == 0, "7g. findIdealIndex-2 ok on array1");
  _check_err(KeyVal_findIndex(&index, kv, "2"), "KeyVal_findIndex");
  ok(index == 0, "7h. findIndex-2 ok on array1");
  // searching something that should go at the end:
  _check_err(KeyVal_findIdealIndex(&index, kv, "3"), "KeyVal_findIdealIndex");
  ok(index == 1, "7j. findIdealIndex-3 ok on array1");
  ok(KeyVal_findIndex(&index, kv, "3") == 2, "7k. findIndex-3 ok on array1");

  // two elements:
  _check_err(KeyVal_setValue(kv, "4", "asdf"), "KeyVal_setValue");
  // searching something that should go in front:
  _check_err(KeyVal_findIdealIndex(&index, kv, "1"), "KeyVal_findIdealIndex");
  ok(index == 0, "7m. findIdealIndex-1 ok on array2");
  ok(KeyVal_findIndex(&index, kv, "1") == 2, "7n. findIndex-1 ok on array2");
  // searching the first thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "2"), "KeyVal_findIdealIndex");
  ok(index == 0, "7p. findIdealIndex-2 ok on array2");
  _check_err(KeyVal_findIndex(&index, kv, "2"), "KeyVal_findIndex");
  ok(index == 0, "7q. findIndex-2 ok on array2");
  // searching something that should go in the middle:
  _check_err(KeyVal_findIdealIndex(&index, kv, "3"), "KeyVal_findIdealIndex");
  ok(index == 1, "7s. findIdealIndex-3 ok on array2");
  ok(KeyVal_findIndex(&index, kv, "3") == 2, "7t. findIndex-3 ok on array2");
  // searching the second thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "4"), "KeyVal_findIdealIndex");
  ok(index == 1, "7v. findIdealIndex-4 ok on array2");
  _check_err(KeyVal_findIndex(&index, kv, "4"), "KeyVal_findIndex");
  ok(index == 1, "7w. findIndex-4 ok on array2");
  // searching something that should go at the end:
  _check_err(KeyVal_findIdealIndex(&index, kv, "5"), "KeyVal_findIdealIndex");
  ok(index == 2, "7y. findIdealIndex-5 ok on array2");
  ok(KeyVal_findIndex(&index, kv, "5") == 2, "7z. findIndex-5 ok on array2");

  // three elements:
  _check_err(KeyVal_setValue(kv, "6", "asdf"), "KeyVal_setValue");
  // searching something that should go in front:
  _check_err(KeyVal_findIdealIndex(&index, kv, "1"), "KeyVal_findIdealIndex");
  ok(index == 0, "7ab. findIdealIndex-1 ok on array3");
  ok(KeyVal_findIndex(&index, kv, "1") == 2, "7ac. findIndex-1 ok on array3");
  // searching the first thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "2"), "KeyVal_findIdealIndex");
  ok(index == 0, "7ae. findIdealIndex-2 ok on array3");
  _check_err(KeyVal_findIndex(&index, kv, "2"), "KeyVal_findIndex");
  ok(index == 0, "7af. findIndex-2 ok on array3");
  // searching something that should go in the middle:
  _check_err(KeyVal_findIdealIndex(&index, kv, "3"), "KeyVal_findIdealIndex");
  ok(index == 1, "7ah. findIdealIndex-3 ok on array3");
  ok(KeyVal_findIndex(&index, kv, "3") == 2, "7ai. findIndex-3 ok on array3");
  // searching the second thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "4"), "KeyVal_findIdealIndex");
  ok(index == 1, "7ak. findIdealIndex-4 ok on array3");
  _check_err(KeyVal_findIndex(&index, kv, "4"), "KeyVal_findIndex");
  ok(index == 1, "7al. findIndex-4 ok on array3");
  // searching something that should go in the middle:
  _check_err(KeyVal_findIdealIndex(&index, kv, "5"), "KeyVal_findIdealIndex");
  ok(index == 2, "7an. findIdealIndex-5 ok on array3");
  ok(KeyVal_findIndex(&index, kv, "5") == 2, "7ao. findIndex-5 ok on array3");
  // searching the second thing that's in it:
  _check_err(KeyVal_findIdealIndex(&index, kv, "6"), "KeyVal_findIdealIndex");
  ok(index == 2, "7aq. findIdealIndex-6 ok on array3");
  _check_err(KeyVal_findIndex(&index, kv, "6"), "KeyVal_findIndex");
  ok(index == 2, "7ar. findIndex-6 ok on array3");
  // searching something that should go at the end:
  _check_err(KeyVal_findIdealIndex(&index, kv, "7"), "KeyVal_findIdealIndex");
  ok(index == 3, "7at. findIdealIndex-7 ok on array3");
  ok(KeyVal_findIndex(&index, kv, "7") == 2, "7au. findIndex-7 ok on array3");

  // we'll assume all larger cases successfully degrade into one of the
  // above.  Yay, partition testing!

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 8
0
static void
test6() {
  // create million-line input:
  // - first key is alphabetic
  // - optional second key is numeric
  // - third key is also numeric because I ran out of ideas
  // - value is just the key backwards

  FILE *fh = fopen(IN, "w");
  if (!fh) {
    printf("[ERROR] cannot write to %s!\n", IN);
    ++test_fails;
    return;
  }

  char key[1024];
  char val[1024];
  char tmp[16];  // this is a surprisingly effective speedup
  // foreach first-key in [a..z]_level:
  for (char a = 'a'; a <= 'z'; ++a) {
//for (char a = 'a'; a <= 'a'; ++a) {

    sprintf(tmp, "%c%s", a, "_level");
    // foreach second-key in none, 1..9:
    for (int b = 10; b >= 0; --b) {  // out of order to test sorting
      if (!b) {
        reverse(val, tmp);
        fprintf(fh, "`%s` = `%s`\n", tmp, val);
        continue;
      }
      // foreach third-key in none, 1..3847: (to make it ~million lines)
      for (int c = 0; c < 3847; ++c) {
//for (int c = 0; c < 1; ++c) {
        if (!c) {
          sprintf(key, "%s::%d", tmp, b);
        } else {
          sprintf(key, "%s::%d::%d", tmp, b, c);
        }
        reverse(val, key);
        fprintf(fh, "`%s` = `%s`\n", key, val);
      }
    }
  }
  fclose(fh);


  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // 6a: reads the huge input (update for later: may want to report load-time?)
  //printf("loading huge file..\n");
  if (!ok(KeyVal_load(kv, IN) == 0, "6a. reads big input")) return;
//printf("done!!\n");

  // 6b: size is right
  unsigned long size;
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  if (!ok(size == 1000246, "6b. big input has 1,000,246 settings")) {
    printf("  -> thinks it has %lu settings\n", size);
  }


  char **keys;
  _check_err(KeyVal_getKeys(&keys, kv, "b_level"), "KeyVal_getKeys");
  if (keys) {
    // count them; should be 11, which means it returns downstream sub-keys only once
    int num_keys = 0;
    for (char **ptr = keys; *ptr; ++ptr) { ++num_keys; }
    if (ok(num_keys == 10, "6c. number of keys under 'b_level' is exactly 10")) {

      // I guess make sure they are what I think they should be.  Probably overkill:
      ok(strcmp(keys[0], "1") == 0, "6e. keys[0]=1");
      ok(strcmp(keys[1], "10") == 0, "6f. keys[1]=10");
      ok(strcmp(keys[2], "2") == 0, "6g. keys[2]=2");
      ok(strcmp(keys[3], "3") == 0, "6h. keys[3]=3");
      ok(strcmp(keys[4], "4") == 0, "6i. keys[4]=4");
      ok(strcmp(keys[5], "5") == 0, "6j. keys[5]=5");
      ok(strcmp(keys[6], "6") == 0, "6k. keys[6]=6");
      ok(strcmp(keys[7], "7") == 0, "6l. keys[7]=7");
      ok(strcmp(keys[8], "8") == 0, "6m. keys[8]=8");
      ok(strcmp(keys[9], "9") == 0, "6n. keys[9]=9");
    }
    for (char **ptr = keys; *ptr; ++ptr) { free(*ptr); }
    free(keys);
  }
  else {
    printf("[UNEXPECTED-3] getKeys should never return a null result\n");
  }

  // check that getAllKeys at least doesn't do nothing:
  _check_err(KeyVal_getAllKeys(&keys, kv), "KeyVal_getAllKeys");
  if (keys) {
    int count = 0;
    while (keys[count]) {
      free(keys[count]);
      ++count;
    }
    free(keys);
    if (!ok(count == 1000246, "6o. getAllKeys returns 1,000,246 keys"))
      printf("  -> thinks it has %d settings\n", count);
  }
  else {
    printf("[UNEXPECTED-4] getAllKeys should never return a null result\n");
  }

  // random getValue, just 'cuz:
  char *value;
  _check_err(KeyVal_getValue(&value, kv, "o_level::3::1500", 0), "KeyVal_getValue");
  if (ok(value != 0, "6p. random key in the middle exists")) {
    ok(strcmp(value, "0051::3::level_o") == 0,
        "6q. random key has the right value");
  }

  // hasValue:
  unsigned char boolflag;
  _check_err(KeyVal_hasValue(&boolflag, kv, "c_level::2::42"), "KeyVal_hasValue");
  ok(boolflag, "6q. hasValue on value");
  _check_err(KeyVal_remove(kv, "b_level::1"), "KeyVal_remove");  // need a strict sub-key to test [6r]
  _check_err(KeyVal_hasValue(&boolflag, kv, "b_level::1"), "KeyVal_hasValue");
  ok(!boolflag, "6r. hasValue on keys");
  _check_err(KeyVal_hasValue(&boolflag, kv, "c_level::moo"), "KeyVal_hasValue");
  ok(!boolflag, "6s. hasValue on nothing");

  // hasKeys:
  _check_err(KeyVal_hasKeys(&boolflag, kv, "c_level::2::42"), "KeyVal_hasKeys");
  ok(!boolflag, "6t. hasKeys on value");
  _check_err(KeyVal_hasKeys(&boolflag, kv, "c_level::2"), "KeyVal_hasKeys");
  ok(boolflag, "6u. hasKeys on keys");
  _check_err(KeyVal_hasKeys(&boolflag, kv, "c_level::moo"), "KeyVal_hasKeys");
  ok(!boolflag, "6v. hasKeys on nothing");

  // exists::
  _check_err(KeyVal_exists(&boolflag, kv, "c_level::2::42"), "KeyVal_exists");
  ok(boolflag, "6w. exists on value");
  _check_err(KeyVal_exists(&boolflag, kv, "c_level::2"), "KeyVal_exists");
  ok(boolflag, "6x. exists on keys");
  _check_err(KeyVal_exists(&boolflag, kv, "c_level::moo"), "KeyVal_exists");
  ok(!boolflag, "6y. exists on nothing");


//KeyVal_save(kv, OUT, 0, 0);  //DEBUG
//printf("--saved to '%s'\n", OUT);

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 9
0
static void
test4() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // intentionally not in alphabetic order:
  _check_err(KeyVal_setValue(kv, "seagram's", "7"), "KeyVal_setValue");
  _check_err(KeyVal_setValue(kv, "jack", "daniel's"), "KeyVal_setValue");

  // 4a. size set from setValues:
  unsigned long size;
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 2, "4a. size=2");

  // 4b: search for first existing:
  char *value;
  _check_err(KeyVal_getValue(&value, kv, "jack", 0), "KeyVal_getValue");
  if (ok(value != 0, "4b. search for existing 'jack'")) {
    // 4c: has the right value:
    ok(strcmp(value, "daniel's") == 0, "4c. jack => daniel's");
  }

  // 4d: search for non-existing key that would be in the middle of existing ones
  _check_err(KeyVal_getValue(&value, kv, "jim::beam", 0), "KeyVal_getValue");
  ok(value == 0, "4d. checking for mid-value nonexistent key");

  // 4e: search for last existing:
  _check_err(KeyVal_getValue(&value, kv, "seagram's", 0), "KeyVal_getValue");
  if (ok(value != 0, "4e. search for existing 'seagram's'")) {
    // 4f: has the right value:
    ok(strcmp(value, "7") == 0, "4f. seagram's => 7");
  }

  // 4g: save it out; should get two lines in order
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output("`jack` = `daniel's`\n`seagram's` = `7`\n") == 0, "4g. writes out correctly");

  // 4h: remove one; should still have the other
  _check_err(KeyVal_remove(kv, "seagram's"), "KeyVal_remove");
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 1, "4h. removing 'seagram's'");
  _check_err(KeyVal_getValue(&value, kv, "jack", 0), "KeyVal_getValue");
  // 4i: removing one didn't affect the other's value, either:
  if (ok(value != 0, "4i. 'jack' ok after removing seagram's")) {
    // 4j: has the right value:
    ok(strcmp(value, "daniel's") == 0, "4j. jack => daniel's, still");
  }

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}
Exemplo n.º 10
0
static void
test3() {
  struct KeyVal *kv;
  _check_err(KeyVal_new(&kv), "KeyVal_new");

  // 3a: unloaded kv should be empty:
  unsigned long size;
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 0, "3a. uninitialized KeyVal empty");
  // 3b: single-element file
  _set_input("`key` = `val`\n");  // minimal typical input
  if (!ok(KeyVal_load(kv, IN) == 0, "3b. reads single-element input")) return;
  // 3c: size set from file input
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 1, "3c. size of single-element input is 1");

  // 3d: search for element before it:
  char *value;
  _check_err(KeyVal_getValue(&value, kv, "asdf", 0), "KeyVal_getValue");
  if (!ok(value == 0, "3d. search for nonexistent 'asdf'")) {
    printf(" - instead found '%s'!\n", value);
  }
  // 3e: search for element after it:
  _check_err(KeyVal_getValue(&value, kv, "zxcv", 0), "KeyVal_getValue");
  ok(value == 0, "3e. search for nonexistent 'zxcv'");

  // 3f: search for it itself:
  _check_err(KeyVal_getValue(&value, kv, "key", 0), "KeyVal_getValue");
  if (ok(value != 0, "3f. search for existing 'key'")) {
    // 3g: has the right value:
    ok(strcmp(value, "val") == 0, "3g. 'key' has value 'val'");
  }

  // 3h: search for subset key:
  _check_err(KeyVal_getValue(&value, kv, "ke", 0), "KeyVal_getValue");
  if (!ok(value == 0, "3h. search for subset 'ke'")) {
    printf(" - instead found '%s'!\n", value);
  }
  // 3i: search for superset key:
  _check_err(KeyVal_getValue(&value, kv, "keysha", 0), "KeyVal_getValue");
  ok(value == 0, "3i. search for superset 'keysha'");


  // 3j: getKeys returns one thing
  char ** keys;
  _check_err(KeyVal_getKeys(&keys, kv, ""), "KeyVal_getKeys");
  if (keys) {
    if (!ok(keys[0]!=0 && !strcmp(keys[0], "key") && keys[1]==0, "3j. getKeys returns ['key']")) {
      printf("keys returned:\n");
      for (char **f = keys;
          *f;
          ++f) {
        printf("  '%s'\n", *f);
      }
    }
    for (char **f = keys;
        *f;
        ++f) {
      free(*f);
    }
    free(keys);
  }
  else {
    printf("[UNEXPECTED-1] getKeys should never return a null result");
  }

  // 3k: hasValue should find it:
  unsigned char boolflag;
  _check_err(KeyVal_hasValue(&boolflag, kv, "key"), "KeyVal_hasValue");
  ok(boolflag == 1, "3k. hasValue finds 'key'");

  // 3l: hasKeys should not segfault on it:
  _check_err(KeyVal_hasKeys(&boolflag, kv, "key"), "KeyVal_hasKeys");
  ok(boolflag == 0, "3l. hasKeys does not segfault on last element, and doesn't report 'key'");

  // 3m: exists should also find it:
  _check_err(KeyVal_exists(&boolflag, kv, "key"), "KeyVal_exists");
  ok(boolflag == 1, "3m. exists finds 'key'");

  // 3n: save it out; should get single value
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output("`key` = `val`\n") == 0, "3n. writes out the single value");


  // 3o: removing element before:
  _check_err(KeyVal_remove(kv, "asdf"), "KeyVal_remove");
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 1, "3o. removing nonexistent 'asdf'");
  // 3p: removing element after:
  _check_err(KeyVal_remove(kv, "zxcv"), "KeyVal_remove");
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 1, "3p. removing nonexistent 'zxcv'");
  // 3q: removing element:
  _check_err(KeyVal_remove(kv, "key"), "KeyVal_remove");
  _check_err(KeyVal_size(&size, kv), "KeyVal_size");
  ok(size == 0, "3q. removing 'key'");

  // 3r: getKeys returns nothing
  _check_err(KeyVal_getKeys(&keys, kv, ""), "KeyVal_getKeys");
  if (keys) {
    ok(keys[0] == 0, "3r: getKeys now returns ['']");
    free(keys);
  }
  else {
    printf("[UNEXPECTED-2] getKeys should never return a null result");
  }

  // 3s: save it out; should get nothing now
  _check_err(KeyVal_save(kv, OUT, 0, 0), "KeyVal_save");
  ok(_check_output("") == 0, "3s. writes out empty file");

  _check_err(KeyVal_delete(kv), "KeyVal_delete");
}