/** Test funckji dictionary_hints(). Wstawienie do słownika 7 słów. Sprawdzenie, czy funkcja zwraca prawidłowe podpowiedzi. */ static void dictionary_hints_test(void** state) { struct dictionary *dict; dict = dictionary_new(); struct word_list *l = malloc(sizeof(word_list)); word_list_init(l); wchar_t *word1 = L"at"; wchar_t *word2 = L"car"; wchar_t *word3 = L"cat"; wchar_t *word4 = L"cats"; wchar_t *word5 = L"cut"; wchar_t *word6 = L"mat"; wchar_t *word7 = L"rat"; dictionary_insert(dict, word1); dictionary_insert(dict, word2); dictionary_insert(dict, word3); dictionary_insert(dict, word4); dictionary_insert(dict, word5); dictionary_insert(dict, word6); dictionary_insert(dict, word7); dictionary_hints(dict, word3, l); assert_string_equal(l->next->word, word1); assert_string_equal(l->next->next->word, word2); assert_string_equal(l->next->next->next->word, word3); assert_string_equal(l->next->next->next->next->word, word4); assert_string_equal(l->next->next->next->next->next->word, word5); assert_string_equal(l->next->next->next->next->next->next->word, word6); assert_string_equal(l->next->next->next->next->next->next->next->word, word7); word_list_done(l); dictionary_done(dict); free(l); }
/** Testuje zapisywanie słownika. @param state Środowisko testowe. */ static void dictionary_save_test(void** state) { struct dictionary *dict = dictionary_new(); FILE *stream; wchar_t *buf = NULL; size_t len; stream = open_wmemstream(&buf, &len); if (stream == NULL) { fprintf(stderr, "Failed to open memory stream\n"); exit(EXIT_FAILURE); } dictionary_insert(dict, L"ciupaga"); assert_true(dictionary_save(dict, stream) == 0); fflush(stream); assert_true(wcscmp(L"ciupaga*^^^^^^^\n0\n", buf) == 0); fseek(stream, 0, SEEK_SET); fclose(stream); # undef free free(buf); # define free(ptr) _test_free(ptr, __FILE__, __LINE__) dictionary_done(dict); }
/** Niszczy środowisko testwowe. @param state Środowisko testowe. @return 0 jeśli się udało, -1 w p.p */ static int dictionary_teardown(void **state) { struct dictionary *dict = *state; dictionary_done(dict); return 0; }
/** Test funkcji dictionary_new(). Stworzenie słownika. */ static void dictionary_new_test(void** state) { struct dictionary *dict; dict = dictionary_new(); assert_true(dict->root->letter == '-'); assert_true(dict->alphabet->letter == '#'); assert_int_equal(dict->root->isInWord, 0); assert_null(dict->alphabet->next); dictionary_done(dict); }
struct dictionary * dictionary_load(FILE* stream) { struct dictionary *dict = NULL; if (deserialize(&dict, stream)) { dictionary_done(dict); dict = NULL; } return dict; }
/// Funkcja sprawdzająca inicjalizację, dodanie słów ze stałych i destrukcję. static void dict_setup_done_test(void **state) { struct dictionary* d = dictionary_new(); assert_non_null(d); assert_int_equal(dictionary_insert(d, first), 1); assert_int_equal(dictionary_insert(d, second), 1); assert_int_equal(dictionary_insert(d, third), 1); assert_int_equal(dictionary_insert(d, forth), 1); assert_int_equal(dictionary_insert(d, fifth), 1); dictionary_done(d); }
/** Testuje wczytywanie drzewa. @param state Środowisko testowe. */ static void dictionary_load_test(void** state) { struct dictionary *dict = NULL; push_word_to_io_mock(L"ciupagą*^^^^^^^\n13\na*b*3*2\n"); dict = dictionary_load(stdin); pop_remaining_chars(); assert_non_null(dict); assert_true(dictionary_find(dict, L"ciupagą")); assert_int_equal(dictionary_hints_max_cost(dict, 2), 13); dictionary_done(dict); }
/** Funkcja main. Główna funkcja programu dict-check. */ int main(int argc, const char **argv) { setlocale(LC_ALL, "pl_PL.UTF-8"); if(argc < 2 || argc > 3) { fwprintf(stderr, L"Błędna liczba argumentów!\n"); usage(); } if(argc == 3 && (argv[1][0] != '-' || argv[1][1] != 'v' || argv[1][2] != '\0')) { fwprintf(stderr, L"Błędny argument!\n"); usage(); } FILE *f = fopen(argv[argc - 1], "r"); if(!f) { fwprintf(stderr, L"Nie udało się załadować pliku %s!\n", argv[argc - 1]); usage(); } bool v_option = argc == 3; struct dictionary * dict = dictionary_load(f); fclose(f); if(dict == NULL) { fwprintf(stderr, L"Nie udało się załadować pliku %s!\n", argv[argc - 1]); usage(); } vector *buffer = read_input(); int line_number = 1; int char_number = 1; for(int index = 0; index < vector_size(buffer); index++, char_number++) { wchar_t c = ((wchar_t *)vector_content(buffer))[index]; if(c == L'\n') { line_number++; char_number = 0; } if(!iswalpha(c)) wprintf(L"%lc", c); else parse_word(&index, &char_number, &line_number, vector_content(buffer), dict, v_option); } vector_done(buffer); dictionary_done(dict); return 0; }
/** * Weryfikuje tekst ze strumienia z podanym słownikiem. * * Wypisuje informacje na standardowe wyjście i opcjonalnie wyjście błędów. * Tekst jest przepisywany na standardowe wyjście, za jednym wyjątkiem: słowa * (zdefiniowane jako spójne ciągi liter, zgodnie z tym, co zwraca funkcja * biblioteczna iswalpha) są poprzedzane znakiem '#', jeśli nie ma ich * w słowniku. * * Opcjonalnie, na wyjście błędów wypisywane są: pozycje, słowa i podpowiedzi * do słów ze standardowego wejścia, których nie ma w słowniku. * * @param [in] dict Słownik, z którym jest weryfikowany tekst. * @param [in] verbose Jeśli "true", drukowane są podpowiedzi na stderr. * @param [in] in Strumień tekstu. Jest wczytywany do napotkania znaku WEOF. */ void process_input(const struct dictionary * dict, bool verbose, FILE * in) { struct parser_state pstate = { .dict = dict, .verbose = verbose, .line_num = 1, .column_num = 1, .last_non_word_column_num = 0, .buffer_iterator = word_buffer }; wchar_t c; do { c = getwc(in); if (iswalpha(c)) { cache_letter(&pstate.buffer_iterator, c); } else { if (word_buffer != pstate.buffer_iterator) process_word(&pstate); process_not_letter(c); } parser_state_update_position(&pstate, c); } while (WEOF != (wint_t) c); } /** * Przetwarza tekst ze standardowego wejścia i sprawdza go ze słownikiem * zapisanym w danej ścieżce. Format słownika musi odpowiadać formatowi * obsługiwanemu przez bibliotekę dictionary. * Szczegóły - patrz także: process_input. * @param [in] dict_path Ścieżka do słownika do wczytania. * @param [in] verbose Gdy flaga jest ustawiona, dodatkowe podpowiedzi * drukowane są na wyjście błędów. * @return Niezerowa wartość w przypadku błędu przy odczycie słownika z dysku. * 0 wpp. */ int process(const char * dict_path, bool verbose) { int error_value; struct dictionary * dict; if (0 != (error_value = load_dictionary(dict_path, &dict))) return error_value; process_input(dict, verbose, stdin); dictionary_done(dict); return 0; }
/** Testuje wstawianie do słownika. @param state Środowisko testowe. */ static void dictionary_insert_test(void** state) { struct dictionary *dict = dictionary_new(); size_t n_words = 4; wchar_t *words[] = {L"wątły", L"wątły", L"wątlejszy", L"łódka"}; for (size_t i = 0; i < n_words; i++) { if (i == 1) assert_false(dictionary_insert(dict, words[i])); else assert_true(dictionary_insert(dict, words[i])); } for (size_t i = 0; i < n_words; i++) assert_true(dictionary_find(dict, words[i])); dictionary_done(dict); }
/** Wyświetlenie listy dostępnych słowników i wczytanie jednego z nich. @param[in] item element menu. @param[in] data wskaźnik na wartość. */ void load_dictionary_from_menu(GtkMenuItem *item, gpointer data) { GtkWidget *dialog; GtkWidget *vbox, *label, *combo; dialog = gtk_dialog_new_with_buttons("Wczytaj słownik", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Lista dostępnych słowników:"); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); // Spuszczane menu combo = gtk_combo_box_text_new(); DIR *dir; struct dirent *ent; if ((dir = opendir(CONF_PATH)) != NULL) { while ((ent = readdir(dir)) != NULL) { if (ent->d_name[0] != '.') gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), ent->d_name); } closedir(dir); } gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { dictionary_save_lang(dict, dictionary_name); dictionary_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); dictionary_done(dict); dict = dictionary_load_lang(dictionary_name); } gtk_widget_destroy(dialog); }
// Procedura ładowania języka static void ChooseLang (GtkMenuItem *item, gpointer data) { GtkWidget *dialog, *vbox, *label, *combo; dialog = gtk_dialog_new_with_buttons("Wybierz...", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Oto lista języków,\ndla których są dostępne słowniki"); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); char *list = NULL; size_t len = 0; if(dictionary_lang_list(&list, &len) < 0) { GtkWidget* err_dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Błąd pobierania listy języków!"); gtk_dialog_run(GTK_DIALOG(err_dialog)); gtk_widget_destroy(err_dialog); return; } // Spuszczane menu combo = gtk_combo_box_text_new(); char* lastFirst = list; for (size_t i = 0; i < len; i++) { if ((list + i)[0] == '\0') { // Dodajemy kolejny element gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), lastFirst); lastFirst = list + i + 1; } } gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) { const char* wybranyJezyk = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); //zapisujemy stary słownik - ktoś mógł coś tam dodać i mógł się zmienić if(strcmp(dict_location, DEFAULT_LOC) != 0) dictionary_save_lang(dict, dict_location); // i ładujemy wybrany struct dictionary* tempDict = dictionary_load_lang(wybranyJezyk); // Jeśli wybrany jest ok, to podmienimy go if(tempDict == NULL) { GtkWidget* err_dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Nie udało się wczytać słownika!"); gtk_dialog_run(GTK_DIALOG(err_dialog)); gtk_widget_destroy(err_dialog); } if(dict != NULL) dictionary_done(dict); dict = tempDict; strcpy(dict_location, wybranyJezyk); //free(wybranyJezyk); } gtk_widget_destroy(dialog); free(list); }
/** Testuje inicjalizację słownika. @param state Środowisko testowe. */ static void dictionary_init_test(void** state) { struct dictionary *dict = dictionary_new(); dictionary_done(dict); }
static void dictionary_add_test(void** state) { struct dictionary * d = dictionary_new(); dictionary_insert(d, test); dictionary_done(d); }
static void dictionary_find_test(void** state) { struct dictionary * d = dictionary_new(); dictionary_insert(d, test); assert_true(dictionary_find(d,test)); dictionary_done(d); }
static void dictionary_delete_test(void** state) { struct dictionary * d = dictionary_new(); dictionary_insert(d, test); assert_int_equal(dictionary_delete(d, test), 1); dictionary_done(d); }
/** Niszczy środowisko do testów @param[in,out] state Środowisko @return Kod błędu */ static int dictionary_teardown(void **state) { dictionary *d = *state; dictionary_done(d); return 0; }
/// Funkcja sprawdzająca inicjalizację i od razu destrukcję słownika. static void dict_new_done_test(void **state) { struct dictionary* d = dictionary_new(); assert_non_null(d); dictionary_done(d); }