void
test_suffix_search(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  const gchar key1[] = "セナ";
  const gchar key2[] = "ナセナセ";
  const gchar key3[] = "Groonga";
  const gchar key4[] = "セナ + Ruby";
  const gchar key5[] = "セナセナ";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key1);
  cut_assert_lookup_add(key2);
  cut_assert_lookup_add(key3);
  cut_assert_lookup_add(key4);
  cut_assert_lookup_add(key5);

  cut_assert_create_hash();
  grn_test_assert_equal_rc(test_data->expected_rc,
                           grn_pat_suffix_search(context, trie,
                                                 test_data->search_key,
                                                 strlen(test_data->search_key),
                                                 hash));
  gcut_assert_equal_list_string(test_data->expected_strings,
                                retrieve_all_keys());
}
void
test_next_with_no_entry(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();
  cut_assert_open_cursor();
  gcut_assert_equal_list_string(NULL, retrieve_all_keys());
}
void
test_by_id_over_offset(void)
{
  default_cursor_flags |= GRN_CURSOR_BY_ID;
  default_cursor_offset = 1;

  cut_assert_create_trie();

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(NULL,
                                retrieve_all_keys());
}
void
test_value(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  const gchar key1[] = "セナ";
  const gchar key2[] = "ナセナセ";
  const gchar key3[] = "Groonga";
  const gchar key4[] = "セナ + Ruby";
  const gchar key5[] = "セナセナ";
  gchar value2[] = "VALUE2";
  gchar value4_1[] = "Groonga";
  gchar value4_2[] = "るびい";
  gchar value5_1[] = "上書きされる値 - overridden value";
  gchar value5_2[] = "上書きされた値 - override value";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key1);
  cut_assert_lookup_add(key2);
  cut_assert_lookup_add(key3);
  cut_assert_lookup_add(key4);
  cut_assert_lookup_add(key5);

  cut_assert_open_cursor();
  while (grn_pat_cursor_next(context, cursor) != GRN_ID_NIL) {
    void *key;
    gchar *null_terminated_key;
    int size;

    size = grn_pat_cursor_get_key(context, cursor, &key);
    null_terminated_key = g_string_free(g_string_new_len(key, size), FALSE);
    if (g_str_equal(null_terminated_key, key2)) {
      grn_pat_cursor_set_value(context, cursor, value2, GRN_OBJ_SET);
    } else if (g_str_equal(null_terminated_key, key4)) {
      grn_pat_cursor_set_value(context, cursor, value4_1, GRN_OBJ_INCR);
      grn_pat_cursor_set_value(context, cursor, value4_2, GRN_OBJ_INCR);
    } else if (g_str_equal(null_terminated_key, key5)) {
      grn_pat_cursor_set_value(context, cursor, value5_1, GRN_OBJ_SET);
      grn_pat_cursor_set_value(context, cursor, value5_2, GRN_OBJ_SET);
    }
  }
  cursor_free();

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(test_data->expected_strings,
                                retrieve_all_keys_and_values());
}
void
test_next_with_one_entry(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  const gchar key[] = "セナ";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key);

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(test_data->expected_strings,
                                retrieve_all_keys());
}
void
test_by_key_descending_max(void)
{
  default_cursor_min = g_strdup("0");
  default_cursor_min_size = strlen(default_cursor_min);
  default_cursor_max = g_strdup("9989");
  default_cursor_max_size = strlen(default_cursor_max);
  default_cursor_flags |= GRN_CURSOR_DESCENDING;

  cut_assert_create_trie();

  cut_assert_lookup_add("997");
  cut_assert_lookup_add("999");
  cut_assert_lookup_add("9998");

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(gcut_take_new_list_string("997", NULL),
                                retrieve_all_keys());
}
void
test_delete(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  const gchar key1[] = "セナ";
  const gchar key2[] = "ナセナセ";
  const gchar key3[] = "Groonga";
  const gchar key4[] = "セナ + Ruby";
  const gchar key5[] = "セナセナ";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key1);
  cut_assert_lookup_add(key2);
  cut_assert_lookup_add(key3);
  cut_assert_lookup_add(key4);
  cut_assert_lookup_add(key5);

  cut_assert_open_cursor();
  while (grn_pat_cursor_next(context, cursor) != GRN_ID_NIL) {
    void *key;
    gchar *null_terminated_key;
    int size;

    size = grn_pat_cursor_get_key(context, cursor, &key);
    null_terminated_key = g_string_free(g_string_new_len(key, size), FALSE);
    if (g_str_equal(null_terminated_key, key1) ||
        g_str_equal(null_terminated_key, key5)) {
      grn_pat_cursor_delete(context, cursor, NULL);
    }
  }
  cursor_free();

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(test_data->expected_strings,
                                retrieve_all_keys());
}
void
test_next_with_multi_entries(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  const gchar key1[] = "セナ";
  const gchar key2[] = "ナセナセ";
  const gchar key3[] = "Groonga";
  const gchar key4[] = "セナ + Ruby";
  const gchar key5[] = "セナセナ";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key1);
  cut_assert_lookup_add(key2);
  cut_assert_lookup_add(key3);
  cut_assert_lookup_add(key4);
  cut_assert_lookup_add(key5);

  cut_assert_open_cursor();
  gcut_assert_equal_list_string(test_data->expected_strings,
                                retrieve_all_keys());
}
void
test_lcp_search(gconstpointer data)
{
  const grn_trie_test_data *test_data = data;
  gchar key[GRN_PAT_MAX_KEY_SIZE];
  const gchar key1[] = "セナ";
  const gchar key2[] = "ナセナセ";
  const gchar key3[] = "Groonga";
  const gchar key4[] = "セナ + Ruby";
  const gchar key5[] = "セナセナ";

  trie_test_data_set_parameters(test_data);

  cut_assert_create_trie();

  cut_assert_lookup_add(key1);
  cut_assert_lookup_add(key2);
  cut_assert_lookup_add(key3);
  cut_assert_lookup_add(key4);
  cut_assert_lookup_add(key5);

  id = grn_pat_lcp_search(context, trie,
                          test_data->search_key,
                          strlen(test_data->search_key));
  if (test_data->expected_key) {
    int size;
    const gchar *null_terminated_key;

    grn_test_assert_not_nil(id);
    size = grn_pat_get_key(context, trie, id, key, sizeof(key));
    null_terminated_key = cut_take_strndup(key, size);
    cut_assert_equal_string(test_data->expected_key, null_terminated_key);
  } else {
    grn_test_assert_nil(id);
  }
}