LCOV - code coverage report
Current view: top level - tests - api_spelling.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core c2b6f1024d3a Lines: 195 195 100.0 %
Date: 2019-05-16 09:13:18 Functions: 9 9 100.0 %
Branches: 473 3044 15.5 %

           Branch data     Line data    Source code
       1                 :            : /** @file api_spelling.cc
       2                 :            :  * @brief Test the spelling correction suggestion API.
       3                 :            :  */
       4                 :            : /* Copyright (C) 2007,2008,2009,2010,2011 Olly Betts
       5                 :            :  * Copyright (C) 2007 Lemur Consulting Ltd
       6                 :            :  *
       7                 :            :  * This program is free software; you can redistribute it and/or modify
       8                 :            :  * it under the terms of the GNU General Public License as published by
       9                 :            :  * the Free Software Foundation; either version 2 of the License, or
      10                 :            :  * (at your option) any later version.
      11                 :            :  *
      12                 :            :  * This program is distributed in the hope that it will be useful,
      13                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15                 :            :  * GNU General Public License for more details.
      16                 :            :  *
      17                 :            :  * You should have received a copy of the GNU General Public License
      18                 :            :  * along with this program; if not, write to the Free Software
      19                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      20                 :            :  */
      21                 :            : 
      22                 :            : #include <config.h>
      23                 :            : 
      24                 :            : #include "api_spelling.h"
      25                 :            : 
      26                 :            : #include <xapian.h>
      27                 :            : 
      28                 :            : #include "apitest.h"
      29                 :            : #include "testsuite.h"
      30                 :            : #include "testutils.h"
      31                 :            : 
      32                 :            : #include <string>
      33                 :            : 
      34                 :            : using namespace std;
      35                 :            : 
      36                 :            : // Test add_spelling() and remove_spelling(), which remote dbs support.
      37                 :          3 : DEFINE_TESTCASE(spell0, spelling || remote) {
      38 [ +  - ][ +  - ]:          3 :     Xapian::WritableDatabase db = get_writable_database();
      39                 :            : 
      40 [ +  - ][ +  - ]:          3 :     db.add_spelling("hello");
      41 [ +  - ][ +  - ]:          3 :     db.add_spelling("cell", 2);
      42         [ +  - ]:          3 :     db.commit();
      43 [ +  - ][ +  - ]:          3 :     db.add_spelling("zig");
      44 [ +  - ][ +  - ]:          3 :     db.add_spelling("ch");
      45 [ +  - ][ +  - ]:          3 :     db.add_spelling("hello", 2);
      46 [ +  - ][ +  - ]:          3 :     db.remove_spelling("hello", 2);
      47 [ +  - ][ +  - ]:          3 :     db.remove_spelling("cell", 6);
      48         [ +  - ]:          3 :     db.commit();
      49 [ +  - ][ +  - ]:          3 :     db.remove_spelling("hello");
      50 [ +  - ][ +  - ]:          3 :     db.remove_spelling("nonsuch");
      51 [ +  - ][ +  - ]:          3 :     db.remove_spelling("zzzzzzzzz", 1000000);
      52 [ +  - ][ +  - ]:          3 :     db.remove_spelling("aarvark");
      53 [ +  - ][ +  - ]:          3 :     db.remove_spelling("hello");
      54         [ +  - ]:          3 :     db.commit();
      55 [ +  - ][ +  - ]:          3 :     db.remove_spelling("hello");
      56                 :            : 
      57                 :          3 :     return true;
      58                 :            : }
      59                 :            : 
      60                 :            : // Test basic spelling correction features.
      61                 :          1 : DEFINE_TESTCASE(spell1, spelling) {
      62 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
      63                 :            : 
      64                 :            :     // Check that the more frequent term is chosen.
      65 [ +  - ][ +  - ]:          1 :     db.add_spelling("hello");
      66 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      67 [ +  - ][ +  - ]:          1 :     db.add_spelling("cell", 2);
      68 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      69         [ +  - ]:          1 :     db.commit();
      70         [ +  - ]:          2 :     Xapian::Database dbr(get_writable_database_as_database());
      71 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      72 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("hell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      73                 :            : 
      74                 :            :     // Check suggestions for single edit errors to "zig".
      75 [ +  - ][ +  - ]:          1 :     db.add_spelling("zig");
      76                 :            :     // Transpositions:
      77 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("izg"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      78 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zgi"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      79                 :            :     // Substitutions:
      80 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("sig"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      81 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zog"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      82 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zif"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      83                 :            :     // Deletions:
      84 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("ig"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      85 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zg"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      86 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zi"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      87                 :            :     // Insertions:
      88 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("azig"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      89 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("zaig"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      90 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("ziag"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      91 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("ziga"), "zig");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      92                 :            : 
      93                 :            :     // Check suggestions for single edit errors to "ch".
      94 [ +  - ][ +  - ]:          1 :     db.add_spelling("ch");
      95                 :            :     // Transpositions:
      96 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hc"), "ch");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      97                 :            :     // Substitutions - we don't handle these for two character words:
      98 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("qh"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
      99 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cq"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     100                 :            :     // Deletions would leave a single character, and we don't handle those.
     101 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("c"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     102 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("h"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     103                 :            :     // Insertions:
     104 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("qch"), "ch");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     105 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cqh"), "ch");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     106 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("chq"), "ch");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     107                 :            : 
     108                 :            :     // Check assorted cases:
     109 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("shello"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     110 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hellot"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     111 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("acell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     112 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cella"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     113 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("acella"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     114 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("helo"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     115 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cll"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     116 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("helol"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     117 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("clel"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     118 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("ecll"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     119 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cll"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     120                 :            : 
     121                 :            :     // Check that edit distance 3 isn't found by default:
     122 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("shelolx"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     123 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("celling"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     124 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("dellin"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     125                 :            : 
     126                 :            :     // Check that edit distance 3 is found if specified:
     127 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("shelolx", 3), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     128 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("celling", 3), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     129 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("dellin", 3), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     130                 :            : 
     131                 :            :     // Make "hello" more frequent than "cell" (3 vs 2).
     132 [ +  - ][ +  - ]:          1 :     db.add_spelling("hello", 2);
     133 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     134         [ +  - ]:          1 :     db.commit();
     135 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cello"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     136 [ +  - ][ +  - ]:          1 :     db.remove_spelling("hello", 2);
     137 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     138                 :            :     // Test "over-removing".
     139 [ +  - ][ +  - ]:          1 :     db.remove_spelling("cell", 6);
     140 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     141         [ +  - ]:          1 :     db.commit();
     142 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     143 [ +  - ][ +  - ]:          1 :     db.remove_spelling("hello");
     144 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("cell"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     145                 :            : 
     146                 :            :     // Test removing words not in the table.
     147 [ +  - ][ +  - ]:          1 :     db.remove_spelling("nonsuch");
     148 [ +  - ][ +  - ]:          1 :     db.remove_spelling("zzzzzzzzz", 1000000);
     149 [ +  - ][ +  - ]:          1 :     db.remove_spelling("aarvark");
     150                 :            : 
     151                 :            :     // Try removing word which was present but no longer is.
     152 [ +  - ][ +  - ]:          1 :     db.remove_spelling("hello");
     153         [ +  - ]:          1 :     db.commit();
     154 [ +  - ][ +  - ]:          1 :     db.remove_spelling("hello");
     155                 :            : 
     156                 :          1 :     return true;
     157                 :            : }
     158                 :            : 
     159                 :            : // Test spelling correction for Unicode.
     160                 :          1 : DEFINE_TESTCASE(spell2, spelling) {
     161 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     162                 :            : 
     163                 :            :     // Check that a UTF-8 sequence counts as a single character.
     164 [ +  - ][ +  - ]:          1 :     db.add_spelling("h\xc3\xb6hle");
     165 [ +  - ][ +  - ]:          1 :     db.add_spelling("ascii");
     166 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hohle", 1), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     167 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hhle", 1), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     168 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("\xf0\xa8\xa8\x8f\xc3\xb6le", 2), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     169 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hh\xc3\xb6l"), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     170 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("as\xc3\xb6\xc3\xb7i"), "ascii");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     171 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("asc\xc3\xb6i\xc3\xb7i"), "ascii");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     172         [ +  - ]:          1 :     db.commit();
     173         [ +  - ]:          2 :     Xapian::Database dbr(get_writable_database_as_database());
     174 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("hohle", 1), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     175 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("hhle", 1), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     176 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("\xf0\xa8\xa8\x8f\xc3\xb6le", 2), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     177 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("hh\xc3\xb6l"), "h\xc3\xb6hle");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     178 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("as\xc3\xb6\xc3\xb7i"), "ascii");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     179 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("asc\xc3\xb6i\xc3\xb7i"), "ascii");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     180                 :            : 
     181                 :          1 :     return true;
     182                 :            : }
     183                 :            : 
     184                 :            : // Test spelling correction with multi databases
     185                 :          1 : DEFINE_TESTCASE(spell3, spelling) {
     186 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db1 = get_writable_database();
     187                 :            :     // We can't just call get_writable_database() since it would delete db1
     188                 :            :     // which doesn't work at all under __WIN32__ and will go wrong elsewhere if
     189                 :            :     // changes to db1 are committed.
     190 [ +  - ][ +  - ]:          2 :     Xapian::WritableDatabase db2 = get_named_writable_database("spell3", "");
                 [ +  - ]
     191                 :            : 
     192 [ +  - ][ +  - ]:          1 :     db1.add_spelling("hello");
     193 [ +  - ][ +  - ]:          1 :     db1.add_spelling("cell", 2);
     194 [ +  - ][ +  - ]:          1 :     db2.add_spelling("hello", 2);
     195 [ +  - ][ +  - ]:          1 :     db2.add_spelling("helo");
     196                 :            : 
     197         [ +  - ]:          2 :     Xapian::Database db;
     198         [ +  - ]:          1 :     db.add_database(db1);
     199         [ +  - ]:          1 :     db.add_database(db2);
     200                 :            : 
     201 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hello"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     202 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     203 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db1.get_spelling_suggestion("hell"), "cell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     204 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db2.get_spelling_suggestion("hell"), "hello");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     205                 :            : 
     206                 :            :     // Test spelling iterator
     207         [ +  - ]:          2 :     Xapian::TermIterator i(db1.spellings_begin());
     208 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "cell");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     209 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     210         [ +  - ]:          1 :     ++i;
     211 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "hello");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     212 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     213         [ +  - ]:          1 :     ++i;
     214 [ -  + ][ #  # ]:          1 :     TEST(i == db1.spellings_end());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     215                 :            : 
     216 [ +  - ][ +  - ]:          1 :     i = db2.spellings_begin();
     217 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "hello");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     218 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     219         [ +  - ]:          1 :     ++i;
     220 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "helo");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     221 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     222         [ +  - ]:          1 :     ++i;
     223 [ -  + ][ #  # ]:          1 :     TEST(i == db2.spellings_end());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     224                 :            : 
     225 [ +  - ][ +  - ]:          1 :     i = db.spellings_begin();
     226 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "cell");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     227 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     228         [ +  - ]:          1 :     ++i;
     229 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "hello");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     230 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 3);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     231         [ +  - ]:          1 :     ++i;
     232 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(*i, "helo");
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     233 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(i.get_termfreq(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     234         [ +  - ]:          1 :     ++i;
     235 [ -  + ][ #  # ]:          1 :     TEST(i == db.spellings_end());
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     236                 :            : 
     237                 :          1 :     return true;
     238                 :            : }
     239                 :            : 
     240                 :            : // Regression test - check that appending works correctly.
     241                 :          1 : DEFINE_TESTCASE(spell4, spelling) {
     242 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     243                 :            : 
     244 [ +  - ][ +  - ]:          1 :     db.add_spelling("check");
     245 [ +  - ][ +  - ]:          1 :     db.add_spelling("pecks", 2);
     246         [ +  - ]:          1 :     db.commit();
     247 [ +  - ][ +  - ]:          1 :     db.add_spelling("becky");
     248         [ +  - ]:          1 :     db.commit();
     249                 :            : 
     250 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("jeck", 2), "pecks");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     251                 :            : 
     252                 :          1 :     return true;
     253                 :            : }
     254                 :            : 
     255                 :            : // Regression test - used to segfault with some input values.
     256                 :          1 : DEFINE_TESTCASE(spell5, spelling) {
     257                 :          1 :     const char * target = "\xe4\xb8\x80\xe4\xba\x9b";
     258                 :            : 
     259 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     260 [ +  - ][ +  - ]:          1 :     db.add_spelling(target);
     261         [ +  - ]:          1 :     db.commit();
     262                 :            : 
     263 [ +  - ][ +  - ]:          2 :     string s = db.get_spelling_suggestion("\xe4\xb8\x8d", 3);
     264 [ +  - ][ -  + ]:          1 :     TEST_EQUAL(s, target);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     265                 :            : 
     266                 :          1 :     return true;
     267                 :            : }
     268                 :            : 
     269                 :            : // Test basic spelling correction features.
     270                 :          1 : DEFINE_TESTCASE(spell6, spelling) {
     271 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     272                 :            : 
     273                 :            :     // Check that the more frequent term is chosen.
     274 [ +  - ][ +  - ]:          1 :     db.add_spelling("hello", 2);
     275 [ +  - ][ +  - ]:          1 :     db.add_spelling("sell", 3);
     276 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "sell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     277         [ +  - ]:          1 :     db.commit();
     278         [ +  - ]:          2 :     Xapian::Database dbr(get_writable_database_as_database());
     279 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("hell"), "sell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     280 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(dbr.get_spelling_suggestion("hell"), "sell");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     281                 :            : 
     282                 :          1 :     return true;
     283                 :            : }
     284                 :            : 
     285                 :            : // Test suggestions when there's an exact match.
     286                 :          1 : DEFINE_TESTCASE(spell7, spelling) {
     287 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     288                 :            : 
     289                 :            :     // Check that the more frequent term is chosen.
     290 [ +  - ][ +  - ]:          1 :     db.add_spelling("word", 57);
     291 [ +  - ][ +  - ]:          1 :     db.add_spelling("wrod", 3);
     292 [ +  - ][ +  - ]:          1 :     db.add_spelling("sword", 56);
     293 [ +  - ][ +  - ]:          1 :     db.add_spelling("words", 57);
     294 [ +  - ][ +  - ]:          1 :     db.add_spelling("ward", 58);
     295         [ +  - ]:          1 :     db.commit();
     296 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("ward"), "");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     297 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("words"), "word");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     298 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("sword"), "word");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     299 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("wrod"), "word");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     300                 :            : 
     301                 :          1 :     return true;
     302                 :            : }
     303                 :            : 
     304                 :            : /// Regression test - repeated trigrams cancelled in 1.2.5 and earlier.
     305                 :          1 : DEFINE_TESTCASE(spell8, spelling) {
     306 [ +  - ][ +  - ]:          1 :     Xapian::WritableDatabase db = get_writable_database();
     307                 :            : 
     308                 :            :     // kin and kin used to cancel out in "skinking".
     309 [ +  - ][ +  - ]:          1 :     db.add_spelling("skinking", 2);
     310 [ +  - ][ +  - ]:          1 :     db.add_spelling("stinking", 1);
     311         [ +  - ]:          1 :     db.commit();
     312 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(db.get_spelling_suggestion("scimkin", 3), "skinking");
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     313                 :            : 
     314                 :          1 :     return true;
     315                 :            : }

Generated by: LCOV version 1.11