LCOV - code coverage report
Current view: top level - tests - api_weight.cc (source / functions) Hit Total Coverage
Test: Test Coverage for xapian-core 954b5873a738 Lines: 950 1019 93.2 %
Date: 2019-06-30 05:20:33 Functions: 73 73 100.0 %
Branches: 1559 8690 17.9 %

           Branch data     Line data    Source code
       1                 :            : /** @file api_weight.cc
       2                 :            :  * @brief tests of Xapian::Weight subclasses
       3                 :            :  */
       4                 :            : /* Copyright (C) 2004,2012,2013,2016,2017,2018 Olly Betts
       5                 :            :  * Copyright (C) 2013 Aarsh Shah
       6                 :            :  * Copyright (C) 2016 Vivek Pal
       7                 :            :  *
       8                 :            :  * This program is free software; you can redistribute it and/or modify
       9                 :            :  * it under the terms of the GNU General Public License as published by
      10                 :            :  * the Free Software Foundation; either version 2 of the License, or
      11                 :            :  * (at your option) any later version.
      12                 :            :  *
      13                 :            :  * This program is distributed in the hope that it will be useful,
      14                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16                 :            :  * GNU General Public License for more details.
      17                 :            :  *
      18                 :            :  * You should have received a copy of the GNU General Public License
      19                 :            :  * along with this program; if not, write to the Free Software
      20                 :            :  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
      21                 :            :  */
      22                 :            : 
      23                 :            : #include <config.h>
      24                 :            : 
      25                 :            : #include "api_weight.h"
      26                 :            : #include <cmath>
      27                 :            : 
      28                 :            : #include <xapian.h>
      29                 :            : 
      30                 :            : #include "apitest.h"
      31                 :            : #include "heap.h"
      32                 :            : #include "testutils.h"
      33                 :            : 
      34                 :            : using namespace std;
      35                 :            : 
      36                 :            : // Test exception for junk after serialised weight.
      37                 :          1 : DEFINE_TESTCASE(tradweight3, !backend) {
      38                 :          1 :     Xapian::TradWeight wt(42);
      39                 :            :     try {
      40                 :          1 :         Xapian::TradWeight t;
      41 [ +  - ][ +  - ]:          1 :         Xapian::TradWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
      42                 :            :         // Make sure we actually use the weight.
      43         [ #  # ]:          0 :         bool empty = t2->name().empty();
      44         [ #  # ]:          0 :         delete t2;
      45         [ #  # ]:          0 :         if (empty)
      46 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised TradWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
      47 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised TradWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
      48 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
      49                 :            :         // Regression test for error in exception message fixed in 1.2.11 and
      50                 :            :         // 1.3.1.
      51 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("BM25") == string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      52 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("Trad") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      53                 :            :     }
      54                 :          1 :     return true;
      55                 :            : }
      56                 :            : 
      57                 :            : // Test Exception for junk after serialised weight.
      58                 :          1 : DEFINE_TESTCASE(unigramlmweight3, !backend) {
      59                 :          1 :     Xapian::LMWeight wt(79898.0, Xapian::Weight::JELINEK_MERCER_SMOOTHING, 0.5, 1.0);
      60                 :            :     try {
      61                 :          1 :         Xapian::LMWeight t;
      62 [ +  - ][ +  - ]:          1 :         Xapian::LMWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
      63                 :            :         // Make sure we actually use the weight.
      64         [ #  # ]:          0 :         bool empty = t2->name().empty();
      65         [ #  # ]:          0 :         delete t2;
      66         [ #  # ]:          0 :         if (empty)
      67 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised LMWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
      68 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised LMWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
      69 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
      70 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("LM") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      71                 :            :     }
      72                 :          1 :     return true;
      73                 :            : }
      74                 :            : 
      75                 :            : // Test exception for junk after serialised weight.
      76                 :          1 : DEFINE_TESTCASE(bm25weight3, !backend) {
      77                 :          1 :     Xapian::BM25Weight wt(2.0, 0.5, 1.3, 0.6, 0.01);
      78                 :            :     try {
      79                 :          1 :         Xapian::BM25Weight b;
      80 [ +  - ][ +  - ]:          1 :         Xapian::BM25Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
      81                 :            :         // Make sure we actually use the weight.
      82         [ #  # ]:          0 :         bool empty = b2->name().empty();
      83         [ #  # ]:          0 :         delete b2;
      84         [ #  # ]:          0 :         if (empty)
      85 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised BM25Weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
      86 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised BM25Weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
      87 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
      88 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("BM25") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
      89                 :            :     }
      90                 :          1 :     return true;
      91                 :            : }
      92                 :            : 
      93                 :            : // Test parameter combinations which should be unaffected by doclength.
      94                 :          7 : DEFINE_TESTCASE(bm25weight4, backend) {
      95 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
      96         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
      97 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
      98         [ +  - ]:         14 :     Xapian::MSet mset;
      99                 :            : 
     100         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25Weight(1, 0, 1, 0, 0.5));
     101 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     102 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     103                 :            :     // Expect: wdf has an effect on weight, but doclen doesn't.
     104 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[0].get_weight(),>,mset[1].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     105 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), mset[2].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     106 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[2].get_weight(),>,mset[3].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     107 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[3].get_weight(), mset[4].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     108                 :            : 
     109         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25Weight(0, 0, 1, 1, 0.5));
     110 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     111 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     112                 :            :     // Expect: neither wdf nor doclen affects weight.
     113 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), mset[4].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     114                 :            : 
     115                 :          7 :     return true;
     116                 :            : }
     117                 :            : 
     118                 :            : /// Test non-zero k2 with zero k1.
     119                 :            : // Regression test for bug fixed in 1.2.17 and 1.3.2.
     120                 :          7 : DEFINE_TESTCASE(bm25weight5, backend) {
     121 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     122         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     123 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
     124         [ +  - ]:         14 :     Xapian::MSet mset;
     125                 :            : 
     126         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25Weight(0, 1, 1, 0.5, 0.5));
     127 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     128 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     129                 :            :     // Expect: wdf has no effect on weight; shorter docs rank higher.
     130         [ +  - ]:          7 :     mset_expect_order(mset, 3, 5, 1, 4, 2);
     131 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), mset[1].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     132 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[1].get_weight(),>,mset[2].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     133 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[2].get_weight(),>,mset[3].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     134 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[3].get_weight(),>,mset[4].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     135                 :            : 
     136                 :          7 :     return true;
     137                 :            : }
     138                 :            : 
     139                 :            : // Test exception for junk after serialised weight.
     140                 :          1 : DEFINE_TESTCASE(bm25plusweight1, !backend) {
     141                 :          1 :     Xapian::BM25PlusWeight wt(2.0, 0.1, 1.3, 0.6, 0.01, 0.5);
     142                 :            :     try {
     143                 :          1 :         Xapian::BM25PlusWeight b;
     144 [ +  - ][ +  - ]:          1 :         Xapian::BM25PlusWeight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     145                 :            :         // Make sure we actually use the weight.
     146         [ #  # ]:          0 :         bool empty = b2->name().empty();
     147         [ #  # ]:          0 :         delete b2;
     148         [ #  # ]:          0 :         if (empty)
     149 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised BM25PlusWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     150 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised BM25PlusWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     151 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     152 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("BM25Plus") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     153                 :            :     }
     154                 :          1 :     return true;
     155                 :            : }
     156                 :            : 
     157                 :            : // Test parameter combinations which should be unaffected by doclength.
     158                 :          7 : DEFINE_TESTCASE(bm25plusweight2, backend) {
     159 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     160         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     161 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
     162         [ +  - ]:         14 :     Xapian::MSet mset;
     163                 :            : 
     164         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25PlusWeight(1, 0, 1, 0, 0.5, 1));
     165 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     166 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     167                 :            :     // Expect: wdf has an effect on weight, but doclen doesn't.
     168 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[0].get_weight(),>,mset[1].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     169 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), mset[2].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     170 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[2].get_weight(),>,mset[3].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     171 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[3].get_weight(), mset[4].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     172                 :            : 
     173         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25PlusWeight(0, 0, 1, 1, 0.5, 1));
     174 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     175 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     176                 :            :     // Expect: neither wdf nor doclen affects weight.
     177 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), mset[4].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     178                 :            : 
     179                 :          7 :     return true;
     180                 :            : }
     181                 :            : 
     182                 :            : // Regression test for a mistake corrected in the BM25+ implementation.
     183                 :          7 : DEFINE_TESTCASE(bm25plusweight3, backend) {
     184 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     185         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     186 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
     187         [ +  - ]:         14 :     Xapian::MSet mset;
     188                 :            : 
     189         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BM25PlusWeight(1, 0, 1, 0.5, 0.5, 1));
     190 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     191 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     192                 :            : 
     193                 :            :     // The value of each doc weight calculated manually from the BM25+ formulae
     194                 :            :     // by using the respective document statistics.
     195 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 0.7920796567487473);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     196 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), 0.7846980783848447);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     197 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[2].get_weight(), 0.7558817623365934);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     198 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[3].get_weight(), 0.7210119356168847);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     199 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[4].get_weight(), 0.7210119356168847);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     200                 :            : 
     201                 :          7 :     return true;
     202                 :            : }
     203                 :            : 
     204                 :            : // Test exception for junk after serialised weight.
     205                 :          1 : DEFINE_TESTCASE(inl2weight1, !backend) {
     206         [ +  - ]:          1 :     Xapian::InL2Weight wt(2.0);
     207                 :            :     try {
     208                 :          1 :         Xapian::InL2Weight b;
     209 [ +  - ][ +  - ]:          1 :         Xapian::InL2Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     210                 :            :         // Make sure we actually use the weight.
     211         [ #  # ]:          0 :         bool empty = b2->name().empty();
     212         [ #  # ]:          0 :         delete b2;
     213         [ #  # ]:          0 :         if (empty)
     214 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised inl2weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     215 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised inl2weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     216 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     217 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("InL2") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     218                 :            :     }
     219                 :            : 
     220                 :          1 :     return true;
     221                 :            : }
     222                 :            : 
     223                 :            : // Test for invalid values of c.
     224                 :          1 : DEFINE_TESTCASE(inl2weight2, !backend) {
     225                 :            :     // InvalidArgumentError should be thrown if the parameter c is invalid.
     226 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     227                 :            :         Xapian::InL2Weight wt(-2.0));
     228                 :            : 
     229 [ +  - ][ -  +  :          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     230                 :            :         Xapian::InL2Weight wt2(0.0));
     231                 :            : 
     232                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     233                 :          1 :     Xapian::InL2Weight weight2;
     234 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::InL2Weight(1.0).serialise());
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     235                 :            : 
     236                 :          1 :     return true;
     237                 :            : }
     238                 :            : 
     239                 :            : // Feature tests for Inl2Weight
     240                 :          7 : DEFINE_TESTCASE(inl2weight3, backend) {
     241 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     242         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     243 [ +  - ][ +  - ]:         14 :     Xapian::Query query("banana");
     244                 :            : 
     245         [ +  - ]:          7 :     enquire.set_query(query);
     246 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::InL2Weight(2.0));
     247                 :            : 
     248         [ +  - ]:         14 :     Xapian::MSet mset1;
     249 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     250 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     251         [ +  - ]:          7 :     mset_expect_order(mset1, 6);
     252                 :            : 
     253                 :            :     /* The value has been calculated in the python interpreter by looking at the
     254                 :            :      * database statistics. */
     255 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 1.559711143842063);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     256                 :            : 
     257                 :            :     // Test with OP_SCALE_WEIGHT.
     258 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     259 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::InL2Weight(2.0));
     260                 :            : 
     261         [ +  - ]:         14 :     Xapian::MSet mset2;
     262 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     263 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     264 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     265 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(15.0 * mset1[0].get_weight(), mset2[0].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     266                 :            : 
     267                 :          7 :     return true;
     268                 :            : }
     269                 :            : 
     270                 :            : // Test exception for junk after serialised weight.
     271                 :          1 : DEFINE_TESTCASE(ifb2weight1, !backend) {
     272         [ +  - ]:          1 :     Xapian::IfB2Weight wt(2.0);
     273                 :            :     try {
     274                 :          1 :         Xapian::IfB2Weight b;
     275 [ +  - ][ +  - ]:          1 :         Xapian::IfB2Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     276                 :            :         // Make sure we actually use the weight.
     277         [ #  # ]:          0 :         bool empty = b2->name().empty();
     278         [ #  # ]:          0 :         delete b2;
     279         [ #  # ]:          0 :         if (empty)
     280 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised IfB2Weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     281 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised IfB2Weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     282 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     283 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("IfB2") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     284                 :            :     }
     285                 :          1 :     return true;
     286                 :            : }
     287                 :            : 
     288                 :            : // Test for invalid values of c.
     289                 :          1 : DEFINE_TESTCASE(ifb2weight2, !backend) {
     290                 :            :     // InvalidArgumentError should be thrown if the parameter c is invalid.
     291 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     292                 :            :         Xapian::IfB2Weight wt(-2.0));
     293                 :            : 
     294 [ +  - ][ -  +  :          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     295                 :            :         Xapian::IfB2Weight wt2(0.0));
     296                 :            : 
     297                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     298                 :          1 :     Xapian::IfB2Weight weight2;
     299 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::IfB2Weight(1.0).serialise());
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     300                 :            : 
     301                 :          1 :     return true;
     302                 :            : }
     303                 :            : 
     304                 :            : // Feature test
     305                 :          7 : DEFINE_TESTCASE(ifb2weight3, backend) {
     306 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     307         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     308 [ +  - ][ +  - ]:         14 :     Xapian::Query query("banana");
     309                 :            : 
     310         [ +  - ]:          7 :     enquire.set_query(query);
     311 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::IfB2Weight(2.0));
     312                 :            : 
     313         [ +  - ]:         14 :     Xapian::MSet mset1;
     314 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     315 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     316                 :            : 
     317                 :            :     /* The value of the weight has been manually calculated using the statistics
     318                 :            :      * of the test database. */
     319 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 3.119422287684126);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     320                 :            : 
     321                 :            :     // Test with OP_SCALE_WEIGHT.
     322 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     323 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::IfB2Weight(2.0));
     324                 :            : 
     325         [ +  - ]:         14 :     Xapian::MSet mset2;
     326 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     327 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     328 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     329 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(15.0 * mset1[0].get_weight(), mset2[0].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     330                 :            : 
     331                 :          7 :     return true;
     332                 :            : }
     333                 :            : 
     334                 :            : // Test exception for junk after serialised weight.
     335                 :          1 : DEFINE_TESTCASE(ineb2weight1, !backend) {
     336         [ +  - ]:          1 :     Xapian::IneB2Weight wt(2.0);
     337                 :            :     try {
     338                 :          1 :         Xapian::IneB2Weight b;
     339 [ +  - ][ +  - ]:          1 :         Xapian::IneB2Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     340                 :            :         // Make sure we actually use the weight.
     341         [ #  # ]:          0 :         bool empty = b2->name().empty();
     342         [ #  # ]:          0 :         delete b2;
     343         [ #  # ]:          0 :         if (empty)
     344 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised ineb2weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     345 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised ineb2weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     346 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     347 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("IneB2") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     348                 :            :     }
     349                 :            : 
     350                 :          1 :     return true;
     351                 :            : }
     352                 :            : 
     353                 :            : // Test for invalid values of c.
     354                 :          1 : DEFINE_TESTCASE(ineb2weight2, !backend) {
     355                 :            :     // InvalidArgumentError should be thrown if parameter c is invalid.
     356 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     357                 :            :         Xapian::IneB2Weight wt(-2.0));
     358                 :            : 
     359 [ +  - ][ -  +  :          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     360                 :            :         Xapian::IneB2Weight wt2(0.0));
     361                 :            : 
     362                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     363                 :          1 :     Xapian::IneB2Weight weight2;
     364 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::IneB2Weight(1.0).serialise());
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     365                 :            : 
     366                 :          1 :     return true;
     367                 :            : }
     368                 :            : 
     369                 :            : // Feature test.
     370                 :          7 : DEFINE_TESTCASE(ineb2weight3, backend) {
     371 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     372         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     373 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
     374         [ +  - ]:          7 :     enquire.set_query(query);
     375 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::IneB2Weight(2.0));
     376                 :            : 
     377         [ +  - ]:         14 :     Xapian::MSet mset1;
     378 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     379 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     380                 :            : 
     381                 :            :     // The third document in the database is 4th in the ranking.
     382                 :            :     /* The weight value has been manually calculated by using the statistics
     383                 :            :      * of the test database. */
     384 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[4].get_weight(), 0.61709730297692400036);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     385                 :            : 
     386                 :            :     // Test with OP_SCALE_WEIGHT.
     387 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     388 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::IneB2Weight(2.0));
     389                 :            : 
     390         [ +  - ]:         14 :     Xapian::MSet mset2;
     391 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     392 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     393                 :            : 
     394 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     395         [ +  + ]:         42 :     for (int i = 0; i < 5; ++i) {
     396 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     397                 :            :     }
     398                 :            : 
     399                 :          7 :     return true;
     400                 :            : }
     401                 :            : 
     402                 :            : // Test exception for junk after serialised weight.
     403                 :          1 : DEFINE_TESTCASE(bb2weight1, !backend) {
     404         [ +  - ]:          1 :     Xapian::BB2Weight wt(2.0);
     405                 :            :     try {
     406                 :          1 :         Xapian::BB2Weight b;
     407 [ +  - ][ +  - ]:          1 :         Xapian::BB2Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     408                 :            :         // Make sure we actually use the weight.
     409         [ #  # ]:          0 :         bool empty = b2->name().empty();
     410         [ #  # ]:          0 :         delete b2;
     411         [ #  # ]:          0 :         if (empty)
     412 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised BB2Weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     413 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised BB2Weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     414 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     415 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("BB2") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     416                 :            :     }
     417                 :          1 :     return true;
     418                 :            : }
     419                 :            : 
     420                 :            : // Test for invalid values of c.
     421                 :          1 : DEFINE_TESTCASE(bb2weight2, !backend) {
     422                 :            :     // InvalidArgumentError should be thrown if the parameter c is invalid.
     423 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     424                 :            :         Xapian::BB2Weight wt(-2.0));
     425                 :            : 
     426 [ +  - ][ -  +  :          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     427                 :            :         Xapian::BB2Weight wt2(0.0));
     428                 :            : 
     429                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     430                 :          1 :     Xapian::BB2Weight weight2;
     431 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::BB2Weight(1.0).serialise());
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     432                 :            : 
     433                 :          1 :     return true;
     434                 :            : }
     435                 :            : 
     436                 :            : // Feature test
     437                 :          7 : DEFINE_TESTCASE(bb2weight3, backend) {
     438 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     439         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     440 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
     441                 :            : 
     442         [ +  - ]:          7 :     enquire.set_query(query);
     443 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BB2Weight(2.0));
     444                 :            : 
     445         [ +  - ]:         14 :     Xapian::MSet mset1;
     446 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     447 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     448                 :            :     /* The third document in the database has the highest weight and is the
     449                 :            :      * first in the mset. */
     450                 :            :     // Value calculated manually by using the statistics of the test database.
     451 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 1.6823696969784483);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     452                 :            : 
     453                 :            :     // Test with OP_SCALE_WEIGHT.
     454 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     455 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BB2Weight(2.0));
     456                 :            : 
     457         [ +  - ]:         14 :     Xapian::MSet mset2;
     458 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     459 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     460                 :            : 
     461 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     462         [ +  + ]:         42 :     for (int i = 0; i < 5; ++i) {
     463 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     464                 :            :     }
     465                 :            : 
     466                 :            :     // Test with OP_SCALE_WEIGHT and a small factor (regression test, as we
     467                 :            :     // were applying the factor to the upper bound twice).
     468 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 1.0 / 1024));
     469 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BB2Weight(2.0));
     470                 :            : 
     471         [ +  - ]:         14 :     Xapian::MSet mset3;
     472 [ +  - ][ +  - ]:          7 :     mset3 = enquire.get_mset(0, 10);
     473 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset3.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     474                 :            : 
     475         [ +  + ]:         42 :     for (int i = 0; i < 5; ++i) {
     476 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset1[i].get_weight(), mset3[i].get_weight() * 1024);
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     477                 :            :     }
     478                 :            : 
     479                 :          7 :     return true;
     480                 :            : }
     481                 :            : 
     482                 :            : // Regression test: we used to calculate log2(0) when there was only one doc.
     483                 :          7 : DEFINE_TESTCASE(bb2weight4, backend) {
     484 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_onedoc");
     485         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     486 [ +  - ][ +  - ]:         14 :     Xapian::Query query("word");
     487                 :            : 
     488         [ +  - ]:          7 :     enquire.set_query(query);
     489         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::BB2Weight());
     490                 :            : 
     491         [ +  - ]:         14 :     Xapian::MSet mset1;
     492 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     493 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     494 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 3.431020621347435);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     495                 :            : 
     496                 :          7 :     return true;
     497                 :            : }
     498                 :            : 
     499                 :            : // Feature test.
     500                 :          7 : DEFINE_TESTCASE(dlhweight1, backend) {
     501 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     502         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     503 [ +  - ][ +  - ]:         14 :     Xapian::Query query("a");
     504                 :            : 
     505         [ +  - ]:          7 :     enquire.set_query(query);
     506         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DLHWeight());
     507                 :            : 
     508         [ +  - ]:         14 :     Xapian::MSet mset1;
     509 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     510 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 3);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     511         [ +  - ]:          7 :     mset_expect_order(mset1, 3, 1, 2);
     512                 :            :     // Weights calculated manually using stats from the database.
     513 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 1.0046477754371292362);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     514 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[1].get_weight(), 0.97621929514640352757);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     515                 :            :     // The following weight would be negative but gets clamped to 0.
     516 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[2].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     517                 :            : 
     518                 :            :     // Test with OP_SCALE_WEIGHT.
     519 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     520         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DLHWeight());
     521                 :            : 
     522         [ +  - ]:         14 :     Xapian::MSet mset2;
     523 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     524 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 3);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     525                 :            : 
     526 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     527 [ +  - ][ +  + ]:         28 :     for (Xapian::doccount i = 0; i < mset2.size(); ++i) {
     528 [ +  - ][ +  - ]:         21 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     529                 :            :     }
     530                 :            : 
     531                 :          7 :     return true;
     532                 :            : }
     533                 :            : 
     534                 :            : // Test exception for junk after serialised weight.
     535                 :          1 : DEFINE_TESTCASE(dlhweight2, !backend) {
     536                 :          1 :     Xapian::DLHWeight wt;
     537                 :            :     try {
     538                 :          1 :         Xapian::DLHWeight t;
     539 [ +  - ][ +  - ]:          1 :         Xapian::DLHWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
     540                 :            :         // Make sure we actually use the weight.
     541         [ #  # ]:          0 :         bool empty = t2->name().empty();
     542         [ #  # ]:          0 :         delete t2;
     543         [ #  # ]:          0 :         if (empty)
     544 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised DLHWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     545 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised DLHWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     546 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     547 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("DLH") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     548                 :            :     }
     549                 :          1 :     return true;
     550                 :            : }
     551                 :            : 
     552                 :            : static void
     553                 :          5 : gen_wdf_eq_doclen_db(Xapian::WritableDatabase& db, const string&)
     554                 :            : {
     555         [ +  - ]:          5 :     Xapian::Document doc;
     556 [ +  - ][ +  - ]:          5 :     doc.add_term("solo", 37);
     557         [ +  - ]:          5 :     db.add_document(doc);
     558                 :          5 : }
     559                 :            : 
     560                 :            : // Test wdf == doclen.
     561                 :          6 : DEFINE_TESTCASE(dlhweight3, generated) {
     562 [ +  - ][ +  - ]:          6 :     Xapian::Database db = get_database("wdf_eq_doclen", gen_wdf_eq_doclen_db);
                 [ +  - ]
     563         [ +  - ]:         12 :     Xapian::Enquire enquire(db);
     564 [ +  - ][ +  - ]:         12 :     Xapian::Query query("solo");
     565                 :            : 
     566         [ +  - ]:          6 :     enquire.set_query(query);
     567         [ +  - ]:          6 :     enquire.set_weighting_scheme(Xapian::DLHWeight());
     568                 :            : 
     569         [ +  - ]:         12 :     Xapian::MSet mset1;
     570 [ +  - ][ +  - ]:          6 :     mset1 = enquire.get_mset(0, 10);
     571 [ +  - ][ -  + ]:          6 :     TEST_EQUAL(mset1.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     572                 :            :     // Weight gets clamped to zero.
     573 [ +  - ][ +  - ]:          6 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     574                 :            : 
     575                 :          6 :     return true;
     576                 :            : }
     577                 :            : 
     578                 :            : // Test exception for junk after serialised weight.
     579                 :          1 : DEFINE_TESTCASE(pl2weight1, !backend) {
     580         [ +  - ]:          1 :     Xapian::PL2Weight wt(2.0);
     581                 :            :     try {
     582                 :          1 :         Xapian::PL2Weight b;
     583 [ +  - ][ +  - ]:          1 :         Xapian::PL2Weight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     584                 :            :         // Make sure we actually use the weight.
     585         [ #  # ]:          0 :         bool empty = b2->name().empty();
     586         [ #  # ]:          0 :         delete b2;
     587         [ #  # ]:          0 :         if (empty)
     588 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised PL2Weight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     589 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised PL2Weight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     590 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     591 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("PL2") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     592                 :            :     }
     593                 :          1 :     return true;
     594                 :            : }
     595                 :            : 
     596                 :            : // Test for invalid values of c.
     597                 :          1 : DEFINE_TESTCASE(pl2weight2, !backend) {
     598                 :            :     // InvalidArgumentError should be thrown if parameter c is invalid.
     599 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
                 [ +  - ]
     600                 :            :         Xapian::PL2Weight wt(-2.0));
     601                 :            : 
     602                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     603                 :          1 :     Xapian::PL2Weight weight2;
     604 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::PL2Weight(1.0).serialise());
         [ +  - ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     605                 :            : 
     606                 :          1 :     return true;
     607                 :            : }
     608                 :            : 
     609                 :            : // Feature Test.
     610                 :          7 : DEFINE_TESTCASE(pl2weight3, backend) {
     611 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     612         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     613 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
     614         [ +  - ]:          7 :     enquire.set_query(query);
     615         [ +  - ]:         14 :     Xapian::MSet mset;
     616                 :            : 
     617 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::PL2Weight(2.0));
     618 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     619 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     620                 :            :     // Expected weight difference calculated in extended precision using stats
     621                 :            :     // from the test database.
     622 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[2].get_weight(),
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     623                 :            :                       mset[3].get_weight() + 0.0086861771701328694);
     624                 :            : 
     625                 :            :     // Test with OP_SCALE_WEIGHT.
     626 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     627 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::PL2Weight(2.0));
     628                 :            : 
     629         [ +  - ]:         14 :     Xapian::MSet mset2;
     630 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     631 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     632 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     633         [ +  + ]:         42 :     for (int i = 0; i < 5; ++i) {
     634 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(15.0 * mset[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     635                 :            :     }
     636                 :            : 
     637                 :          7 :     return true;
     638                 :            : }
     639                 :            : 
     640                 :            : // Test exception for junk after serialised weight.
     641                 :          1 : DEFINE_TESTCASE(pl2plusweight1, !backend) {
     642         [ +  - ]:          1 :     Xapian::PL2PlusWeight wt(2.0, 0.9);
     643                 :            :     try {
     644                 :          1 :         Xapian::PL2PlusWeight b;
     645 [ +  - ][ +  - ]:          1 :         Xapian::PL2PlusWeight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     646                 :            :         // Make sure we actually use the weight.
     647         [ #  # ]:          0 :         bool empty = b2->name().empty();
     648         [ #  # ]:          0 :         delete b2;
     649         [ #  # ]:          0 :         if (empty)
     650 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised PL2PlusWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     651 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised PL2PlusWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     652 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     653 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("PL2Plus") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     654                 :            :     }
     655                 :          1 :     return true;
     656                 :            : }
     657                 :            : 
     658                 :            : // Test for invalid values of parameters, c and delta.
     659                 :          1 : DEFINE_TESTCASE(pl2plusweight2, !backend) {
     660                 :            :     // InvalidArgumentError should be thrown if parameter c is invalid.
     661 [ +  - ][ -  + ]:          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ -  + ][ -  +  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     662                 :            :         Xapian::PL2PlusWeight wt(-2.0, 0.9));
     663                 :            : 
     664                 :            :     // InvalidArgumentError should be thrown if parameter delta is invalid.
     665   [ -  +  #  #  :          1 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
          #  #  #  #  #  
          #  #  #  #  #  
           +  - ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     666                 :            :         Xapian::PL2PlusWeight wt(1.0, -1.9));
     667                 :            : 
     668                 :          1 :     return true;
     669                 :            : }
     670                 :            : 
     671                 :            : // Test for default values of parameters, c and delta.
     672                 :          1 : DEFINE_TESTCASE(pl2plusweight3, !backend) {
     673                 :          1 :     Xapian::PL2PlusWeight weight2;
     674                 :            : 
     675                 :            :     /* Parameter c should be set to 1.0 by constructor if none is given. */
     676 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::PL2PlusWeight(1.0, 0.8).serialise());
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     677                 :            : 
     678                 :            :     /* Parameter delta should be set to 0.8 by constructor if none is given. */
     679 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::PL2PlusWeight(1.0, 0.8).serialise());
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     680                 :            : 
     681                 :          1 :     return true;
     682                 :            : }
     683                 :            : 
     684                 :            : // Feature Test 1 for PL2PlusWeight.
     685                 :          7 : DEFINE_TESTCASE(pl2plusweight4, backend) {
     686 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     687         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     688 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
     689         [ +  - ]:         14 :     Xapian::MSet mset;
     690                 :            : 
     691 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::PL2PlusWeight(2.0, 0.8));
     692 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     693 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     694                 :            :     // Expected weight difference calculated in extended precision using stats
     695                 :            :     // from the test database.
     696 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[2].get_weight(),
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     697                 :            :                       mset[3].get_weight() + 0.0086861771701328694);
     698                 :            : 
     699                 :          7 :     return true;
     700                 :            : }
     701                 :            : 
     702                 :            : // Feature Test 2 for PL2PlusWeight
     703                 :          7 : DEFINE_TESTCASE(pl2plusweight5, backend) {
     704 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     705         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     706 [ +  - ][ +  - ]:         14 :     Xapian::Query query("word");
     707         [ +  - ]:          7 :     enquire.set_query(query);
     708         [ +  - ]:         14 :     Xapian::MSet mset;
     709                 :            : 
     710 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::PL2PlusWeight(1.0, 0.8));
     711 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     712                 :            :     // Expect MSet contains two documents having query "word".
     713 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     714                 :            :     // Expect Document 2 has higher weight than document 4 because
     715                 :            :     // "word" appears more no. of times in document 2 than document 4.
     716         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     717                 :            : 
     718                 :            :     // Test with OP_SCALE_WEIGHT.
     719 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     720 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::PL2PlusWeight(1.0, 0.8));
     721                 :            : 
     722         [ +  - ]:         14 :     Xapian::MSet mset2;
     723 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     724 [ +  - ][ +  - ]:          7 :     TEST_EQUAL(mset2.size(), mset.size());
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     725 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     726 [ +  - ][ +  + ]:         21 :     for (Xapian::doccount i = 0; i < mset.size(); ++i) {
     727 [ +  - ][ +  - ]:         14 :         TEST_EQUAL_DOUBLE(15.0 * mset[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     728                 :            :     }
     729                 :            : 
     730                 :          7 :     return true;
     731                 :            : }
     732                 :            : 
     733                 :            : // Feature test
     734                 :          7 : DEFINE_TESTCASE(dphweight1, backend) {
     735 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     736         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     737 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
     738                 :            : 
     739         [ +  - ]:          7 :     enquire.set_query(query);
     740         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DPHWeight());
     741                 :            : 
     742         [ +  - ]:         14 :     Xapian::MSet mset1;
     743 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
     744 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     745                 :            :     /* The weight has been calculated manually by using the statistics of the
     746                 :            :      * test database. */
     747 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[2].get_weight() - mset1[4].get_weight(), 0.542623617687990167);
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     748                 :            : 
     749                 :            :     // Test with OP_SCALE_WEIGHT.
     750 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     751         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DPHWeight());
     752                 :            : 
     753         [ +  - ]:         14 :     Xapian::MSet mset2;
     754 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     755 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     756 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     757         [ +  + ]:         42 :     for (int i = 0; i < 5; ++i) {
     758 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     759                 :            :     }
     760                 :            : 
     761                 :          7 :     return true;
     762                 :            : }
     763                 :            : 
     764                 :            : // Test exception for junk after serialised weight.
     765                 :          1 : DEFINE_TESTCASE(dphweight2, !backend) {
     766                 :          1 :     Xapian::DPHWeight wt;
     767                 :            :     try {
     768                 :          1 :         Xapian::DPHWeight t;
     769 [ +  - ][ +  - ]:          1 :         Xapian::DPHWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
     770                 :            :         // Make sure we actually use the weight.
     771         [ #  # ]:          0 :         bool empty = t2->name().empty();
     772         [ #  # ]:          0 :         delete t2;
     773         [ #  # ]:          0 :         if (empty)
     774 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised DPHWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     775 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised DPHWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     776 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     777 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("DPH") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     778                 :            :     }
     779                 :          1 :     return true;
     780                 :            : }
     781                 :            : 
     782                 :            : // Test wdf == doclen.
     783                 :          6 : DEFINE_TESTCASE(dphweight3, generated) {
     784 [ +  - ][ +  - ]:          6 :     Xapian::Database db = get_database("wdf_eq_doclen", gen_wdf_eq_doclen_db);
                 [ +  - ]
     785         [ +  - ]:         12 :     Xapian::Enquire enquire(db);
     786 [ +  - ][ +  - ]:         12 :     Xapian::Query query("solo");
     787                 :            : 
     788         [ +  - ]:          6 :     enquire.set_query(query);
     789         [ +  - ]:          6 :     enquire.set_weighting_scheme(Xapian::DPHWeight());
     790                 :            : 
     791         [ +  - ]:         12 :     Xapian::MSet mset1;
     792 [ +  - ][ +  - ]:          6 :     mset1 = enquire.get_mset(0, 10);
     793 [ +  - ][ -  + ]:          6 :     TEST_EQUAL(mset1.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     794                 :            :     // Weight gets clamped to zero.
     795 [ +  - ][ +  - ]:          6 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     796                 :            : 
     797                 :          6 :     return true;
     798                 :            : }
     799                 :            : 
     800                 :            : // Test for various cases of normalization string.
     801                 :          1 : DEFINE_TESTCASE(tfidfweight1, !backend) {
     802                 :            :     // InvalidArgumentError should be thrown if normalization string is invalid
     803 [ +  - ][ +  - ]:          3 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     804                 :            :         Xapian::TfIdfWeight b("JOHN_LENNON"));
     805                 :            : 
     806 [ +  - ][ +  - ]:          2 :     TEST_EXCEPTION(Xapian::InvalidArgumentError,
           [ -  +  #  #  
          #  #  #  #  #  
             #  #  #  #  
              # ][ -  + ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
           #  # ][ +  - ]
     807                 :            :         Xapian::TfIdfWeight b("LOL"));
     808                 :            : 
     809                 :            :     /* Normalization string should be set to "ntn" by constructor if none is
     810                 :            :       given. */
     811         [ +  - ]:          1 :     Xapian::TfIdfWeight weight2;
     812 [ +  - ][ +  - ]:          1 :     TEST_EQUAL(weight2.serialise(), Xapian::TfIdfWeight("ntn").serialise());
         [ +  - ][ +  - ]
           [ -  +  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     813                 :            : 
     814                 :          2 :     return true;
     815                 :            : }
     816                 :            : 
     817                 :            : // Test exception for junk after serialised weight.
     818                 :          1 : DEFINE_TESTCASE(tfidfweight2, !backend) {
     819 [ +  - ][ +  - ]:          1 :     Xapian::TfIdfWeight wt("ntn");
     820                 :            :     try {
     821         [ +  - ]:          1 :         Xapian::TfIdfWeight b;
     822 [ +  - ][ +  - ]:          1 :         Xapian::TfIdfWeight * b2 = b.unserialise(wt.serialise() + "X");
                 [ -  + ]
     823                 :            :         // Make sure we actually use the weight.
     824         [ #  # ]:          0 :         bool empty = b2->name().empty();
     825         [ #  # ]:          0 :         delete b2;
     826         [ #  # ]:          0 :         if (empty)
     827 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised TfIdfWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
     828 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised TfIdfWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
     829 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
     830 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("TfIdf") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     831                 :            :     }
     832                 :          1 :     return true;
     833                 :            : }
     834                 :            : 
     835                 :            : // Feature tests for various normalization functions.
     836                 :          7 : DEFINE_TESTCASE(tfidfweight3, backend) {
     837 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     838         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     839 [ +  - ][ +  - ]:         14 :     Xapian::Query query("word");
     840         [ +  - ]:         14 :     Xapian::MSet mset;
     841                 :            : 
     842                 :            :     // Check for "ntn" when termfreq != N
     843         [ +  - ]:          7 :     enquire.set_query(query);
     844 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("ntn"));
                 [ +  - ]
     845 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     846 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     847                 :            :     // doc 2 should have higher weight than 4 as only tf(wdf) will dominate.
     848         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     849 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 8.0 * log(6.0 / 2));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     850                 :            : 
     851                 :            :     // Check that wqf is taken into account.
     852 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word", 2));
                 [ +  - ]
     853 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("ntn"));
                 [ +  - ]
     854         [ +  - ]:         14 :     Xapian::MSet mset2 = enquire.get_mset(0, 10);
     855 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     856                 :            :     // wqf is 2, so weights should be doubled.
     857 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight() * 2, mset2[0].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     858 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight() * 2, mset2[1].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     859                 :            : 
     860                 :            :     // Test with OP_SCALE_WEIGHT.
     861 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
     862 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("ntn"));
                 [ +  - ]
     863 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
     864 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     865                 :            :     // doc 2 should have higher weight than 4 as only tf(wdf) will dominate.
     866         [ +  - ]:          7 :     mset_expect_order(mset2, 2, 4);
     867 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     868 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(15 * mset[0].get_weight(), mset2[0].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     869                 :            : 
     870                 :            :     // check for "nfn" when termfreq != N
     871         [ +  - ]:          7 :     enquire.set_query(query);
     872 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("nfn"));
                 [ +  - ]
     873 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     874 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     875         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     876 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 8.0 / 2);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     877                 :            : 
     878                 :            :     // check for "nsn" when termfreq != N
     879         [ +  - ]:          7 :     enquire.set_query(query);
     880 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("nsn"));
                 [ +  - ]
     881 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     882 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     883         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     884 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 8.0 * pow(log(6.0 / 2), 2.0));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     885                 :            : 
     886                 :            :     // Check for "bnn" and for both branches of 'b'.
     887 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("test"));
                 [ +  - ]
     888 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("bnn"));
                 [ +  - ]
     889 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     890 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     891         [ +  - ]:          7 :     mset_expect_order(mset, 1);
     892 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 1.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     893                 :            : 
     894                 :            :     // Check for "lnn" and for both branches of 'l'.
     895 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word"));
                 [ +  - ]
     896 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("lnn"));
                 [ +  - ]
     897 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     898 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     899         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     900 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 1 + log(8.0)); // idfn=1 and so wt=tfn=1+log(tf)
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     901 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), 1.0);         // idfn=1 and wt=tfn=1+log(tf)=1+log(1)=1
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     902                 :            : 
     903                 :            :     // Check for "snn"
     904 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
     905 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("snn")); // idf=1 and tfn=tf*tf
                 [ +  - ]
     906 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     907 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     908         [ +  - ]:          7 :     mset_expect_order(mset, 2, 1, 4, 3, 5);
     909 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 9.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     910 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[4].get_weight(), 1.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     911                 :            : 
     912                 :            :     // Check for "ntn" when termfreq=N
     913 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("this"));  // N=termfreq and so idfn=0 for "t"
                 [ +  - ]
     914 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("ntn"));
                 [ +  - ]
     915 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     916 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 6);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     917         [ +  - ]:          7 :     mset_expect_order(mset, 1, 2, 3, 4, 5, 6);
     918         [ +  + ]:         49 :     for (int i = 0; i < 6; ++i) {
     919 [ +  - ][ +  - ]:         42 :         TEST_EQUAL_DOUBLE(mset[i].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     920                 :            :     }
     921                 :            : 
     922                 :            :     // Check for "npn" and for both branches of 'p'
     923 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("this"));  // N=termfreq and so idfn=0 for "p"
                 [ +  - ]
     924 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("npn"));
                 [ +  - ]
     925 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     926 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 6);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     927         [ +  - ]:          7 :     mset_expect_order(mset, 1, 2, 3, 4, 5, 6);
     928         [ +  + ]:         49 :     for (int i = 0; i < 6; ++i) {
     929 [ +  - ][ +  - ]:         42 :         TEST_EQUAL_DOUBLE(mset[i].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     930                 :            :     }
     931                 :            : 
     932                 :            :     // Check for "Lnn".
     933 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word"));
                 [ +  - ]
     934 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("Lnn"));
                 [ +  - ]
     935 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     936 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     937         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     938 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), (1 + log(8.0)) / (1 + log(81.0 / 56.0)));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     939 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), (1 + log(1.0)) / (1 + log(31.0 / 26.0)));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     940                 :            : 
     941 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word"));
                 [ +  - ]
     942 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("npn"));
                 [ +  - ]
     943 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     944 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     945         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     946 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight(), 8 * log((6.0 - 2) / 2));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     947 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight(), 1 * log((6.0 - 2) / 2));
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     948                 :            : 
     949                 :          7 :     return true;
     950                 :            : }
     951                 :            : 
     952                 :            : // Feature tests for pivoted normalization functions.
     953                 :          7 : DEFINE_TESTCASE(tfidfweight4, backend) {
     954 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
     955         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
     956 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
     957         [ +  - ]:         14 :     Xapian::MSet mset;
     958                 :            : 
     959                 :            :     // Check for "PPn" normalization string.
     960         [ +  - ]:          7 :     enquire.set_query(query);
     961 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("PPn", 0.2, 1.0));
                 [ +  - ]
     962 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     963 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     964                 :            :     // Shorter docs should ranker higher if wqf is equal among all the docs.
     965 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[0].get_weight(),>,mset[1].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     966 [ +  - ][ +  - ]:          7 :     TEST_REL(mset[2].get_weight(),>,mset[3].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     967                 :            : 
     968                 :            :     // Check that wqf is taken into account.
     969 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("paragraph", 2));
                 [ +  - ]
     970 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("PPn", 0.2, 1.0));
                 [ +  - ]
     971         [ +  - ]:         14 :     Xapian::MSet mset2 = enquire.get_mset(0, 10);
     972 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     973                 :            :     // wqf is 2, so weights should be doubled.
     974 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[0].get_weight() * 2, mset2[0].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     975 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset[1].get_weight() * 2, mset2[1].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     976                 :            : 
     977                 :            :     // check for "nPn" which represents "xPx"
     978 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word"));
                 [ +  - ]
     979 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("nPn", 0.2, 1.0));
                 [ +  - ]
     980 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     981 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     982                 :            :     // Expect doc 2 with query "word" to have higher weight than doc 4.
     983         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     984                 :            : 
     985                 :            :     // check for "Ptn" which represents "Pxx"
     986 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query("word"));
                 [ +  - ]
     987 [ +  - ][ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::TfIdfWeight("Ptn", 0.2, 1.0));
                 [ +  - ]
     988 [ +  - ][ +  - ]:          7 :     mset = enquire.get_mset(0, 10);
     989 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset.size(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     990                 :            :     // Expect doc 2 with query "word" to have higher weight than doc 4.
     991         [ +  - ]:          7 :     mset_expect_order(mset, 2, 4);
     992                 :            : 
     993                 :          7 :     return true;
     994                 :            : }
     995                 :            : 
     996         [ -  + ]:         72 : class CheckInitWeight : public Xapian::Weight {
     997                 :            :   public:
     998                 :            :     double factor;
     999                 :            : 
    1000                 :            :     unsigned & zero_inits, & non_zero_inits;
    1001                 :            : 
    1002                 :         20 :     CheckInitWeight(unsigned &z, unsigned &n)
    1003                 :         20 :         : factor(-1.0), zero_inits(z), non_zero_inits(n) {
    1004                 :         20 :         need_stat(DOC_LENGTH);
    1005                 :         20 :     }
    1006                 :            : 
    1007                 :         12 :     void init(double factor_) {
    1008                 :         12 :         factor = factor_;
    1009         [ +  + ]:         12 :         if (factor == 0.0)
    1010                 :          4 :             ++zero_inits;
    1011                 :            :         else
    1012                 :          8 :             ++non_zero_inits;
    1013                 :         12 :     }
    1014                 :            : 
    1015                 :         16 :     Weight * clone() const {
    1016                 :         16 :         return new CheckInitWeight(zero_inits, non_zero_inits);
    1017                 :            :     }
    1018                 :            : 
    1019                 :         40 :     double get_sumpart(Xapian::termcount, Xapian::termcount,
    1020                 :            :                        Xapian::termcount) const {
    1021                 :         40 :         return 1.0;
    1022                 :            :     }
    1023                 :            : 
    1024                 :         32 :     double get_maxpart() const { return 1.0; }
    1025                 :            : 
    1026                 :         20 :     double get_sumextra(Xapian::termcount doclen, Xapian::termcount) const {
    1027                 :         20 :         return 1.0 / doclen;
    1028                 :            :     }
    1029                 :            : 
    1030                 :         16 :     double get_maxextra() const { return 1.0; }
    1031                 :            : };
    1032                 :            : 
    1033                 :            : /// Regression test - check init() is called for the term-indep Weight obj.
    1034                 :          4 : DEFINE_TESTCASE(checkinitweight1, backend && !multi && !remote) {
    1035 [ +  - ][ +  - ]:          4 :     Xapian::Database db = get_database("apitest_simpledata");
    1036         [ +  - ]:          8 :     Xapian::Enquire enquire(db);
    1037                 :            :     Xapian::Query q(Xapian::Query::OP_AND,
    1038 [ +  - ][ +  - ]:          8 :                     Xapian::Query("this"), Xapian::Query("paragraph"));
         [ +  - ][ +  - ]
                 [ +  - ]
    1039         [ +  - ]:          4 :     enquire.set_query(q);
    1040                 :          4 :     unsigned zero_inits = 0, non_zero_inits = 0;
    1041                 :          8 :     CheckInitWeight wt(zero_inits, non_zero_inits);
    1042         [ +  - ]:          4 :     enquire.set_weighting_scheme(wt);
    1043         [ +  - ]:          8 :     Xapian::MSet mset = enquire.get_mset(0, 3);
    1044 [ -  + ][ #  # ]:          4 :     TEST_EQUAL(zero_inits, 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1045 [ -  + ][ #  # ]:          4 :     TEST_EQUAL(non_zero_inits, 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1046                 :          4 :     return true;
    1047                 :            : }
    1048                 :            : 
    1049         [ -  + ]:      18704 : class CheckStatsWeight : public Xapian::Weight {
    1050                 :            :   public:
    1051                 :            :     double factor;
    1052                 :            : 
    1053                 :            :     Xapian::Database db;
    1054                 :            : 
    1055                 :            :     string term1;
    1056                 :            : 
    1057                 :            :     // When testing OP_SYNONYM, term2 is also set.
    1058                 :            :     // When testing OP_WILDCARD, term2 == "*".
    1059                 :            :     // When testing a repeated term, term2 == "=" for the first occurrence and
    1060                 :            :     // "_" for subsequent occurrences.
    1061                 :            :     mutable string term2;
    1062                 :            : 
    1063                 :            :     Xapian::termcount & sum;
    1064                 :            :     Xapian::termcount & sum_squares;
    1065                 :            : 
    1066                 :            :     mutable Xapian::termcount len_upper;
    1067                 :            :     mutable Xapian::termcount len_lower;
    1068                 :            :     mutable Xapian::termcount wdf_upper;
    1069                 :            : 
    1070                 :       5252 :     CheckStatsWeight(const Xapian::Database & db_,
    1071                 :            :                      const string & term1_,
    1072                 :            :                      const string & term2_,
    1073                 :            :                      Xapian::termcount & sum_,
    1074                 :            :                      Xapian::termcount & sum_squares_)
    1075                 :            :         : factor(-1.0), db(db_), term1(term1_), term2(term2_),
    1076                 :            :           sum(sum_), sum_squares(sum_squares_),
    1077 [ +  - ][ +  - ]:       5252 :           len_upper(0), len_lower(Xapian::termcount(-1)), wdf_upper(0)
                 [ +  - ]
    1078                 :            :     {
    1079                 :       5252 :         need_stat(COLLECTION_SIZE);
    1080                 :       5252 :         need_stat(RSET_SIZE);
    1081                 :       5252 :         need_stat(AVERAGE_LENGTH);
    1082                 :       5252 :         need_stat(TERMFREQ);
    1083                 :       5252 :         need_stat(RELTERMFREQ);
    1084                 :       5252 :         need_stat(QUERY_LENGTH);
    1085                 :       5252 :         need_stat(WQF);
    1086                 :       5252 :         need_stat(WDF);
    1087                 :       5252 :         need_stat(DOC_LENGTH);
    1088                 :       5252 :         need_stat(DOC_LENGTH_MIN);
    1089                 :       5252 :         need_stat(DOC_LENGTH_MAX);
    1090                 :       5252 :         need_stat(WDF_MAX);
    1091                 :       5252 :         need_stat(COLLECTION_FREQ);
    1092                 :       5252 :         need_stat(UNIQUE_TERMS);
    1093                 :       5252 :     }
    1094                 :            : 
    1095                 :        495 :     CheckStatsWeight(const Xapian::Database & db_,
    1096                 :            :                      const string & term_,
    1097                 :            :                      Xapian::termcount & sum_,
    1098                 :            :                      Xapian::termcount & sum_squares_)
    1099         [ +  - ]:        495 :         : CheckStatsWeight(db_, term_, string(), sum_, sum_squares_) { }
    1100                 :            : 
    1101                 :       2948 :     void init(double factor_) {
    1102                 :       2948 :         factor = factor_;
    1103                 :       2948 :     }
    1104                 :            : 
    1105                 :       4100 :     Weight * clone() const {
    1106         [ +  - ]:       4100 :         auto res = new CheckStatsWeight(db, term1, term2, sum, sum_squares);
    1107         [ +  + ]:       4100 :         if (term2 == "=") {
    1108                 :            :             // The object passed to Enquire::set_weighting_scheme() is cloned
    1109                 :            :             // right away, and then cloned again for each term, and then
    1110                 :            :             // potentially once more for the term-independent weight
    1111                 :            :             // contribution.  In the repeated case, we want to handle the first
    1112                 :            :             // actual term specially, so we arrange for that to have "=" for
    1113                 :            :             // term2, and subsequent clones to have "_", so that we accumulate
    1114                 :            :             // sum and sum_squares on the first occurrence only.
    1115                 :        792 :             term2 = "_";
    1116                 :            :         }
    1117                 :       4100 :         return res;
    1118                 :            :     }
    1119                 :            : 
    1120                 :       2579 :     double get_sumpart(Xapian::termcount wdf, Xapian::termcount doclen,
    1121                 :            :                        Xapian::termcount uniqueterms) const {
    1122                 :       2579 :         Xapian::doccount num_docs = db.get_doccount();
    1123 [ -  + ][ #  # ]:       2579 :         TEST_EQUAL(get_collection_size(), num_docs);
    1124 [ -  + ][ #  # ]:       2579 :         TEST_EQUAL(get_rset_size(), 0);
    1125 [ -  + ][ #  # ]:       2579 :         TEST_EQUAL(get_average_length(), db.get_avlength());
    1126 [ +  + ][ +  + ]:       2579 :         if (term2.empty() || term2 == "=" || term2 == "_") {
         [ +  + ][ +  + ]
    1127 [ -  + ][ #  # ]:       1911 :             TEST_EQUAL(get_termfreq(), db.get_termfreq(term1));
    1128 [ -  + ][ #  # ]:       1911 :             TEST_EQUAL(get_collection_freq(), db.get_collection_freq(term1));
    1129         [ +  + ]:       1911 :             if (term2.empty()) {
    1130 [ -  + ][ #  # ]:        735 :                 TEST_EQUAL(get_query_length(), 1);
    1131                 :            :             } else {
    1132 [ -  + ][ #  # ]:       1911 :                 TEST_EQUAL(get_query_length(), 2);
    1133                 :            :             }
    1134                 :            :         } else {
    1135                 :        668 :             Xapian::doccount tfmax = 0, tfsum = 0;
    1136                 :        668 :             Xapian::termcount cfmax = 0, cfsum = 0;
    1137 [ +  - ][ +  + ]:        668 :             if (term2 == "*") {
    1138                 :            :                 // OP_WILDCARD case.
    1139         [ +  - ]:       1560 :                 for (auto&& t = db.allterms_begin(term1);
           [ +  -  +  + ]
    1140                 :       1040 :                      t != db.allterms_end(term1); ++t) {
    1141         [ +  - ]:        452 :                     Xapian::doccount tf = t.get_termfreq();
    1142 [ +  - ][ +  - ]:        452 :                     tout << "->" << *t << " " << tf << endl;
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1143                 :        452 :                     tfsum += tf;
    1144                 :        452 :                     tfmax = max(tfmax, tf);
    1145 [ +  - ][ +  - ]:        452 :                     Xapian::termcount cf = db.get_collection_freq(*t);
    1146                 :        452 :                     cfsum += cf;
    1147                 :        452 :                     cfmax = max(cfmax, cf);
    1148                 :         68 :                 }
    1149 [ -  + ][ #  # ]:         68 :                 TEST_EQUAL(get_query_length(), 1);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1150                 :            :             } else {
    1151                 :            :                 // OP_SYNONYM case.
    1152         [ +  - ]:        600 :                 Xapian::doccount tf1 = db.get_termfreq(term1);
    1153         [ +  - ]:        600 :                 Xapian::doccount tf2 = db.get_termfreq(term2);
    1154                 :        600 :                 tfsum = tf1 + tf2;
    1155                 :        600 :                 tfmax = max(tf1, tf2);
    1156         [ +  - ]:        600 :                 Xapian::termcount cf1 = db.get_collection_freq(term1);
    1157         [ +  - ]:        600 :                 Xapian::termcount cf2 = db.get_collection_freq(term2);
    1158                 :        600 :                 cfsum = cf1 + cf2;
    1159                 :        600 :                 cfmax = max(cf1, cf2);
    1160 [ -  + ][ #  # ]:        600 :                 TEST_EQUAL(get_query_length(), 2);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1161                 :            :             }
    1162                 :            :             // Synonym occurs at least as many times as any term.
    1163 [ -  + ][ #  # ]:        668 :             TEST_REL(get_termfreq(), >=, tfmax);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1164 [ -  + ][ #  # ]:        668 :             TEST_REL(get_collection_freq(), >=, cfmax);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1165                 :            :             // Synonym can't occur more times than the terms do.
    1166 [ -  + ][ #  # ]:        668 :             TEST_REL(get_termfreq(), <=, tfsum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1167 [ -  + ][ #  # ]:        668 :             TEST_REL(get_collection_freq(), <=, cfsum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1168                 :            :             // Synonym can't occur more times than there are documents/terms.
    1169 [ -  + ][ #  # ]:        668 :             TEST_REL(get_termfreq(), <=, num_docs);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1170                 :        668 :             double total_term_occurences = get_average_length() * num_docs;
    1171 [ -  + ][ #  # ]:        668 :             TEST_REL(get_collection_freq(), <=, total_term_occurences);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1172                 :            :         }
    1173 [ -  + ][ #  # ]:       2579 :         TEST_EQUAL(get_reltermfreq(), 0);
    1174 [ -  + ][ #  # ]:       2579 :         TEST_EQUAL(get_wqf(), 1);
    1175 [ -  + ][ #  # ]:       2579 :         TEST_REL(doclen,>=,len_lower);
    1176 [ -  + ][ #  # ]:       2579 :         TEST_REL(doclen,<=,len_upper);
    1177 [ -  + ][ #  # ]:       2579 :         TEST_REL(uniqueterms,>=,1);
    1178 [ -  + ][ #  # ]:       2579 :         TEST_REL(uniqueterms,<=,doclen);
    1179 [ -  + ][ #  # ]:       2579 :         TEST_REL(wdf,<=,wdf_upper);
    1180         [ +  + ]:       2579 :         if (term2 != "_") {
    1181                 :       1991 :             sum += wdf;
    1182                 :       1991 :             sum_squares += wdf * wdf;
    1183                 :            :         }
    1184                 :       2579 :         return 1.0;
    1185                 :            :     }
    1186                 :            : 
    1187                 :       3058 :     double get_maxpart() const {
    1188         [ +  + ]:       3058 :         if (len_upper == 0) {
    1189                 :       1672 :             len_lower = get_doclength_lower_bound();
    1190                 :       1672 :             len_upper = get_doclength_upper_bound();
    1191                 :       1672 :             wdf_upper = get_wdf_upper_bound();
    1192                 :            :         }
    1193                 :       3058 :         return 1.0;
    1194                 :            :     }
    1195                 :            : 
    1196                 :       1991 :     double get_sumextra(Xapian::termcount doclen, Xapian::termcount) const {
    1197                 :       1991 :         return 1.0 / doclen;
    1198                 :            :     }
    1199                 :            : 
    1200                 :       5104 :     double get_maxextra() const { return 1.0; }
    1201                 :            : };
    1202                 :            : 
    1203                 :            : /// Check the weight subclass gets the correct stats.
    1204                 :          5 : DEFINE_TESTCASE(checkstatsweight1, backend && !remote) {
    1205 [ +  - ][ +  - ]:          5 :     Xapian::Database db = get_database("apitest_simpledata");
    1206         [ +  - ]:         10 :     Xapian::Enquire enquire(db);
    1207                 :         10 :     Xapian::TermIterator a;
    1208 [ +  - ][ +  - ]:        500 :     for (a = db.allterms_begin(); a != db.allterms_end(); ++a) {
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
    1209         [ +  - ]:        495 :         const string & term = *a;
    1210 [ +  - ][ +  - ]:        495 :         enquire.set_query(Xapian::Query(term));
    1211                 :        495 :         Xapian::termcount sum = 0;
    1212                 :        495 :         Xapian::termcount sum_squares = 0;
    1213         [ +  - ]:        990 :         CheckStatsWeight wt(db, term, sum, sum_squares);
    1214         [ +  - ]:        495 :         enquire.set_weighting_scheme(wt);
    1215 [ +  - ][ +  - ]:        990 :         Xapian::MSet mset = enquire.get_mset(0, db.get_doccount());
    1216                 :            : 
    1217                 :            :         // The document order in the multi-db case isn't the same as the
    1218                 :            :         // postlist order on the combined DB, so it's hard to compare the
    1219                 :            :         // wdf for each document in the Weight objects, but we can sum
    1220                 :            :         // the wdfs and the squares of the wdfs which provides a decent
    1221                 :            :         // check that we're not getting the wrong wdf values (it ensures
    1222                 :            :         // they have the right mean and standard deviation).
    1223                 :        495 :         Xapian::termcount expected_sum = 0;
    1224                 :        495 :         Xapian::termcount expected_sum_squares = 0;
    1225                 :        990 :         Xapian::PostingIterator i;
    1226 [ +  - ][ +  - ]:       1230 :         for (i = db.postlist_begin(term); i != db.postlist_end(term); ++i) {
         [ +  - ][ +  + ]
    1227         [ +  - ]:        735 :             Xapian::termcount wdf = i.get_wdf();
    1228                 :        735 :             expected_sum += wdf;
    1229                 :        735 :             expected_sum_squares += wdf * wdf;
    1230                 :            :         }
    1231 [ -  + ][ #  # ]:        495 :         TEST_EQUAL(sum, expected_sum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1232 [ -  + ][ #  # ]:        495 :         TEST_EQUAL(sum_squares, expected_sum_squares);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1233                 :        495 :     }
    1234                 :          5 :     return true;
    1235                 :            : }
    1236                 :            : 
    1237                 :            : /// Check the weight subclass gets the correct stats with OP_SYNONYM.
    1238                 :            : // Regression test for bugs fixed in 1.4.1.
    1239                 :          5 : DEFINE_TESTCASE(checkstatsweight2, backend && !remote) {
    1240 [ +  - ][ +  - ]:          5 :     Xapian::Database db = get_database("apitest_simpledata");
    1241         [ +  - ]:         10 :     Xapian::Enquire enquire(db);
    1242                 :         10 :     Xapian::TermIterator a;
    1243 [ +  - ][ +  - ]:        255 :     for (a = db.allterms_begin(); a != db.allterms_end(); ++a) {
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1244         [ +  - ]:        250 :         const string & term1 = *a;
    1245 [ +  - ][ +  - ]:        250 :         if (++a == db.allterms_end()) break;
                 [ +  + ]
    1246 [ +  - ][ +  + ]:        495 :         const string & term2 = *a;
    1247                 :            :         Xapian::Query q(Xapian::Query::OP_SYNONYM,
    1248 [ +  - ][ +  - ]:        490 :                         Xapian::Query(term1), Xapian::Query(term2));
                 [ +  - ]
    1249 [ +  - ][ +  - ]:        245 :         tout << q.get_description() << endl;
                 [ +  - ]
    1250         [ +  - ]:        245 :         enquire.set_query(q);
    1251                 :        245 :         Xapian::termcount sum = 0;
    1252                 :        245 :         Xapian::termcount sum_squares = 0;
    1253         [ +  - ]:        490 :         CheckStatsWeight wt(db, term1, term2, sum, sum_squares);
    1254         [ +  - ]:        245 :         enquire.set_weighting_scheme(wt);
    1255 [ +  - ][ +  - ]:        490 :         Xapian::MSet mset = enquire.get_mset(0, db.get_doccount());
    1256                 :            : 
    1257                 :            :         // The document order in the multi-db case isn't the same as the
    1258                 :            :         // postlist order on the combined DB, so it's hard to compare the
    1259                 :            :         // wdf for each document in the Weight objects, but we can sum
    1260                 :            :         // the wdfs and the squares of the wdfs which provides a decent
    1261                 :            :         // check that we're not getting the wrong wdf values (it ensures
    1262                 :            :         // they have the right mean and standard deviation).
    1263                 :        245 :         Xapian::termcount expected_sum = 0;
    1264                 :        245 :         Xapian::termcount expected_sum_squares = 0;
    1265         [ +  - ]:        490 :         Xapian::PostingIterator i = db.postlist_begin(term1);
    1266         [ +  - ]:        490 :         Xapian::PostingIterator j = db.postlist_begin(term2);
    1267 [ +  - ][ +  - ]:        245 :         Xapian::docid did1 = *i, did2 = *j;
    1268                 :            :         while (true) {
    1269                 :            :             // To calculate expected_sum_squares correctly we need to square
    1270                 :            :             // the sum per document.
    1271                 :            :             Xapian::termcount wdf;
    1272         [ +  + ]:        600 :             if (did1 == did2) {
    1273 [ +  - ][ +  - ]:        130 :                 wdf = i.get_wdf() + j.get_wdf();
    1274                 :        130 :                 did1 = did2 = 0;
    1275         [ +  + ]:        470 :             } else if (did1 < did2) {
    1276         [ +  - ]:        220 :                 wdf = i.get_wdf();
    1277                 :        220 :                 did1 = 0;
    1278                 :            :             } else {
    1279         [ +  - ]:        250 :                 wdf = j.get_wdf();
    1280                 :        250 :                 did2 = 0;
    1281                 :            :             }
    1282                 :        600 :             expected_sum += wdf;
    1283                 :        600 :             expected_sum_squares += wdf * wdf;
    1284                 :            : 
    1285         [ +  + ]:        600 :             if (did1 == 0) {
    1286 [ +  - ][ +  + ]:        350 :                 if (++i != db.postlist_end(term1)) {
    1287         [ +  - ]:        105 :                     did1 = *i;
    1288                 :            :                 } else {
    1289         [ +  + ]:        245 :                     if (did2 == Xapian::docid(-1)) break;
    1290                 :        265 :                     did1 = Xapian::docid(-1);
    1291                 :            :                 }
    1292                 :            :             }
    1293         [ +  + ]:        515 :             if (did2 == 0) {
    1294 [ +  - ][ +  + ]:        380 :                 if (++j != db.postlist_end(term2)) {
    1295         [ +  - ]:        135 :                     did2 = *j;
    1296                 :            :                 } else {
    1297         [ +  + ]:        245 :                     if (did1 == Xapian::docid(-1)) break;
    1298                 :        355 :                     did2 = Xapian::docid(-1);
    1299                 :            :                 }
    1300                 :            :             }
    1301                 :            :         }
    1302                 :            :         // The OP_SYNONYM's wdf should be equal to the sum of the wdfs of
    1303                 :            :         // the individual terms.
    1304 [ -  + ][ #  # ]:        245 :         TEST_EQUAL(sum, expected_sum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1305 [ -  + ][ #  # ]:        245 :         TEST_REL(sum_squares, >=, expected_sum_squares);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1306                 :        245 :     }
    1307                 :          5 :     return true;
    1308                 :            : }
    1309                 :            : 
    1310                 :            : /// Check the weight subclass gets the correct stats with OP_WILDCARD.
    1311                 :            : // Regression test for bug fixed in 1.4.1.
    1312                 :            : // Don't run with multi-database, as the termfreq checks don't work
    1313                 :            : // there - FIXME: Investigate this - it smells like a bug.
    1314                 :          4 : DEFINE_TESTCASE(checkstatsweight3, backend && !remote && !multi) {
    1315                 :            :     struct PlCmp {
    1316                 :        332 :         bool operator()(const Xapian::PostingIterator& a,
    1317                 :            :                         const Xapian::PostingIterator& b) {
    1318                 :        332 :             return *a < *b;
    1319                 :            :         }
    1320                 :            :     };
    1321                 :            : 
    1322 [ +  - ][ +  - ]:          4 :     Xapian::Database db = get_database("apitest_simpledata");
    1323         [ +  - ]:          8 :     Xapian::Enquire enquire(db);
    1324                 :          8 :     Xapian::TermIterator a;
    1325                 :            :     static const char * const testcases[] = {
    1326                 :            :         "a", // a* matches all documents, but no term matches all.
    1327                 :            :         "pa", // Expands to only "paragraph", matching 5.
    1328                 :            :         "zulu", // No matches.
    1329                 :            :         "th", // Term "this" matches all documents.
    1330                 :            :     };
    1331         [ +  + ]:         20 :     for (auto pattern : testcases) {
    1332 [ +  - ][ +  - ]:         16 :         Xapian::Query q(Xapian::Query::OP_WILDCARD, pattern);
    1333 [ +  - ][ +  - ]:         16 :         tout << q.get_description() << endl;
                 [ +  - ]
    1334         [ +  - ]:         16 :         enquire.set_query(q);
    1335                 :         16 :         Xapian::termcount sum = 0;
    1336                 :         16 :         Xapian::termcount sum_squares = 0;
    1337 [ +  - ][ +  - ]:         32 :         CheckStatsWeight wt(db, pattern, "*", sum, sum_squares);
                 [ +  - ]
    1338         [ +  - ]:         16 :         enquire.set_weighting_scheme(wt);
    1339 [ +  - ][ +  - ]:         32 :         Xapian::MSet mset = enquire.get_mset(0, db.get_doccount());
    1340                 :            : 
    1341                 :            :         // The document order in the multi-db case isn't the same as the
    1342                 :            :         // postlist order on the combined DB, so it's hard to compare the
    1343                 :            :         // wdf for each document in the Weight objects, but we can sum
    1344                 :            :         // the wdfs and the squares of the wdfs which provides a decent
    1345                 :            :         // check that we're not getting the wrong wdf values (it ensures
    1346                 :            :         // they have the right mean and standard deviation).
    1347                 :         16 :         Xapian::termcount expected_sum = 0;
    1348                 :         16 :         Xapian::termcount expected_sum_squares = 0;
    1349                 :         32 :         vector<Xapian::PostingIterator> postlists;
    1350 [ +  - ][ +  - ]:        276 :         for (auto&& t = db.allterms_begin(pattern);
           [ +  -  +  + ]
    1351         [ +  - ]:        184 :              t != db.allterms_end(pattern); ++t) {
    1352 [ +  - ][ +  - ]:         76 :             postlists.emplace_back(db.postlist_begin(*t));
                 [ +  - ]
    1353                 :         16 :         }
    1354         [ +  - ]:         16 :         Heap::make(postlists.begin(), postlists.end(), PlCmp());
    1355                 :         16 :         Xapian::docid did = 0;
    1356                 :         16 :         Xapian::termcount wdf = 0;
    1357         [ +  + ]:        168 :         while (!postlists.empty()) {
    1358         [ +  - ]:        152 :             Xapian::docid did_new = *postlists.front();
    1359         [ +  - ]:        152 :             Xapian::termcount wdf_new = postlists.front().get_wdf();
    1360 [ +  - ][ +  + ]:        152 :             if (++(postlists.front()) == Xapian::PostingIterator()) {
    1361         [ +  - ]:         76 :                 Heap::pop(postlists.begin(), postlists.end(), PlCmp());
    1362                 :         76 :                 postlists.pop_back();
    1363                 :            :             } else {
    1364         [ +  - ]:         76 :                 Heap::replace(postlists.begin(), postlists.end(), PlCmp());
    1365                 :            :             }
    1366         [ +  + ]:        152 :             if (did_new != did) {
    1367                 :        124 :                 expected_sum += wdf;
    1368                 :        124 :                 expected_sum_squares += wdf * wdf;
    1369                 :        124 :                 wdf = 0;
    1370                 :        124 :                 did = did_new;
    1371                 :            :             }
    1372                 :        152 :             wdf += wdf_new;
    1373                 :            :         }
    1374                 :         16 :         expected_sum += wdf;
    1375                 :         16 :         expected_sum_squares += wdf * wdf;
    1376                 :            :         // The OP_SYNONYM's wdf should be equal to the sum of the wdfs of
    1377                 :            :         // the individual terms.
    1378 [ -  + ][ #  # ]:         16 :         TEST_EQUAL(sum, expected_sum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1379 [ -  + ][ #  # ]:         16 :         TEST_REL(sum_squares, >=, expected_sum_squares);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1380                 :         16 :     }
    1381                 :          4 :     return true;
    1382                 :            : }
    1383                 :            : 
    1384                 :            : /// Check the stats for a repeated term are correct.
    1385                 :            : // Regression test for bug fixed in 1.4.6.  Doesn't work with
    1386                 :            : // multi as the weight object is cloned more times.
    1387                 :          4 : DEFINE_TESTCASE(checkstatsweight4, backend && !remote && !multi) {
    1388 [ +  - ][ +  - ]:          4 :     Xapian::Database db = get_database("apitest_simpledata");
    1389         [ +  - ]:          8 :     Xapian::Enquire enquire(db);
    1390                 :          8 :     Xapian::TermIterator a;
    1391 [ +  - ][ +  - ]:        400 :     for (a = db.allterms_begin(); a != db.allterms_end(); ++a) {
         [ +  - ][ +  - ]
         [ +  - ][ +  + ]
    1392         [ +  - ]:        396 :         const string & term = *a;
    1393 [ +  - ][ +  - ]:        792 :         enquire.set_query(Xapian::Query(term, 1, 1) |
                 [ +  - ]
    1394         [ +  - ]:        396 :                           Xapian::Query(term, 1, 2));
    1395                 :        396 :         Xapian::termcount sum = 0;
    1396                 :        396 :         Xapian::termcount sum_squares = 0;
    1397 [ +  - ][ +  - ]:        792 :         CheckStatsWeight wt(db, term, "=", sum, sum_squares);
    1398         [ +  - ]:        396 :         enquire.set_weighting_scheme(wt);
    1399 [ +  - ][ +  - ]:        792 :         Xapian::MSet mset = enquire.get_mset(0, db.get_doccount());
    1400                 :            : 
    1401                 :            :         // The document order in the multi-db case isn't the same as the
    1402                 :            :         // postlist order on the combined DB, so it's hard to compare the
    1403                 :            :         // wdf for each document in the Weight objects, but we can sum
    1404                 :            :         // the wdfs and the squares of the wdfs which provides a decent
    1405                 :            :         // check that we're not getting the wrong wdf values (it ensures
    1406                 :            :         // they have the right mean and standard deviation).
    1407                 :        396 :         Xapian::termcount expected_sum = 0;
    1408                 :        396 :         Xapian::termcount expected_sum_squares = 0;
    1409                 :        792 :         Xapian::PostingIterator i;
    1410 [ +  - ][ +  - ]:        984 :         for (i = db.postlist_begin(term); i != db.postlist_end(term); ++i) {
         [ +  - ][ +  + ]
    1411         [ +  - ]:        588 :             Xapian::termcount wdf = i.get_wdf();
    1412                 :        588 :             expected_sum += wdf;
    1413                 :        588 :             expected_sum_squares += wdf * wdf;
    1414                 :            :         }
    1415 [ -  + ][ #  # ]:        396 :         TEST_EQUAL(sum, expected_sum);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1416 [ -  + ][ #  # ]:        396 :         TEST_EQUAL(sum_squares, expected_sum_squares);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1417                 :        396 :     }
    1418                 :          4 :     return true;
    1419                 :            : }
    1420                 :            : 
    1421                 :            : // Two stage should perform same as Jelinek mercer if smoothing parameter for mercer is kept 1 in both.
    1422                 :          7 : DEFINE_TESTCASE(unigramlmweight4, backend) {
    1423 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
    1424         [ +  - ]:         14 :     Xapian::Enquire enquire1(db);
    1425         [ +  - ]:         14 :     Xapian::Enquire enquire2(db);
    1426 [ +  - ][ +  - ]:          7 :     enquire1.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1427         [ +  - ]:         14 :     Xapian::MSet mset1;
    1428 [ +  - ][ +  - ]:          7 :     enquire2.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1429         [ +  - ]:         14 :     Xapian::MSet mset2;
    1430                 :            :     // 5 documents available with term paragraph so mset size should be 5
    1431         [ +  - ]:          7 :     enquire1.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::TWO_STAGE_SMOOTHING, 1, 0));
    1432         [ +  - ]:          7 :     enquire2.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::JELINEK_MERCER_SMOOTHING, 1, 0));
    1433 [ +  - ][ +  - ]:          7 :     mset1 = enquire1.get_mset(0, 10);
    1434 [ +  - ][ +  - ]:          7 :     mset2 = enquire2.get_mset(0, 10);
    1435                 :            : 
    1436 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1437 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[1].get_weight(), mset2[1].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1438                 :          7 :     return true;
    1439                 :            : }
    1440                 :            : 
    1441                 :            : /* Test for checking if we don't use smoothing all
    1442                 :            :  * of them should give same result i.e wdf_double/len_double */
    1443                 :          7 : DEFINE_TESTCASE(unigramlmweight5, backend) {
    1444 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
    1445         [ +  - ]:         14 :     Xapian::Enquire enquire1(db);
    1446         [ +  - ]:         14 :     Xapian::Enquire enquire2(db);
    1447         [ +  - ]:         14 :     Xapian::Enquire enquire3(db);
    1448         [ +  - ]:         14 :     Xapian::Enquire enquire4(db);
    1449 [ +  - ][ +  - ]:          7 :     enquire1.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1450         [ +  - ]:         14 :     Xapian::MSet mset1;
    1451 [ +  - ][ +  - ]:          7 :     enquire2.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1452         [ +  - ]:         14 :     Xapian::MSet mset2;
    1453 [ +  - ][ +  - ]:          7 :     enquire3.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1454         [ +  - ]:         14 :     Xapian::MSet mset3;
    1455 [ +  - ][ +  - ]:          7 :     enquire4.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1456         [ +  - ]:         14 :     Xapian::MSet mset4;
    1457                 :            :     // 5 documents available with term paragraph so mset size should be 5
    1458         [ +  - ]:          7 :     enquire1.set_weighting_scheme(Xapian::LMWeight(10000.0, Xapian::Weight::TWO_STAGE_SMOOTHING, 0, 0));
    1459         [ +  - ]:          7 :     enquire2.set_weighting_scheme(Xapian::LMWeight(10000.0, Xapian::Weight::JELINEK_MERCER_SMOOTHING, 0, 0));
    1460         [ +  - ]:          7 :     enquire3.set_weighting_scheme(Xapian::LMWeight(10000.0, Xapian::Weight::ABSOLUTE_DISCOUNT_SMOOTHING, 0, 0));
    1461         [ +  - ]:          7 :     enquire4.set_weighting_scheme(Xapian::LMWeight(10000.0, Xapian::Weight::DIRICHLET_SMOOTHING, 0, 0));
    1462                 :            : 
    1463 [ +  - ][ +  - ]:          7 :     mset1 = enquire1.get_mset(0, 10);
    1464 [ +  - ][ +  - ]:          7 :     mset2 = enquire2.get_mset(0, 10);
    1465 [ +  - ][ +  - ]:          7 :     mset3 = enquire3.get_mset(0, 10);
    1466 [ +  - ][ +  - ]:          7 :     mset4 = enquire4.get_mset(0, 10);
    1467                 :            : 
    1468 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1469 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1470 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset3.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1471 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset4.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1472         [ +  + ]:         42 :     for (size_t i = 0; i < 5; ++i) {
    1473 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset3[i].get_weight(), mset4[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1474 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset2[i].get_weight(), mset4[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1475 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1476 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset3[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1477 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset1[i].get_weight(), mset4[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1478 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(mset1[i].get_weight(), mset3[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1479                 :            :     }
    1480                 :          7 :     return true;
    1481                 :            : }
    1482                 :            : 
    1483                 :            : // Test Exception for junk after serialised weight (with Dir+ enabled).
    1484                 :          1 : DEFINE_TESTCASE(unigramlmweight6, !backend) {
    1485                 :          1 :     Xapian::LMWeight wt(0, Xapian::Weight::DIRICHLET_SMOOTHING, 0.5, 1.0);
    1486                 :            :     try {
    1487                 :          1 :         Xapian::LMWeight d;
    1488 [ +  - ][ +  - ]:          1 :         Xapian::LMWeight * d2 = d.unserialise(wt.serialise() + "X");
                 [ -  + ]
    1489                 :            :         // Make sure we actually use the weight.
    1490         [ #  # ]:          0 :         bool empty = d2->name().empty();
    1491         [ #  # ]:          0 :         delete d2;
    1492         [ #  # ]:          0 :         if (empty)
    1493 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised LMWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
    1494 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised LMWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
    1495 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
    1496 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("LM") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1497                 :            :     }
    1498                 :          1 :     return true;
    1499                 :            : }
    1500                 :            : 
    1501                 :            : // Feature test for Dir+ function.
    1502                 :          7 : DEFINE_TESTCASE(unigramlmweight7, backend) {
    1503 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
    1504         [ +  - ]:         14 :     Xapian::Enquire enquire1(db);
    1505         [ +  - ]:         14 :     Xapian::Enquire enquire2(db);
    1506 [ +  - ][ +  - ]:          7 :     enquire1.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1507 [ +  - ][ +  - ]:          7 :     enquire2.set_query(Xapian::Query("paragraph"));
                 [ +  - ]
    1508         [ +  - ]:         14 :     Xapian::MSet mset1;
    1509         [ +  - ]:         14 :     Xapian::MSet mset2;
    1510                 :            : 
    1511         [ +  - ]:          7 :     enquire1.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::DIRICHLET_SMOOTHING, 2000, 0));
    1512         [ +  - ]:          7 :     enquire2.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::DIRICHLET_PLUS_SMOOTHING, 2000, 0.05));
    1513                 :            : 
    1514 [ +  - ][ +  - ]:          7 :     mset1 = enquire1.get_mset(0, 10);
    1515 [ +  - ][ +  - ]:          7 :     mset2 = enquire2.get_mset(0, 10);
    1516                 :            : 
    1517                 :            :     // mset size should be 5
    1518 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1519 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1520                 :            : 
    1521                 :            :     // Expect mset weights associated with Dir+ more than mset weights by Dir
    1522                 :            :     // because of the presence of extra weight component in Dir+ function.
    1523 [ +  - ][ +  - ]:          7 :     TEST_REL(mset2[0].get_weight(),>,mset1[0].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1524 [ +  - ][ +  - ]:          7 :     TEST_REL(mset2[1].get_weight(),>,mset1[1].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1525 [ +  - ][ +  - ]:          7 :     TEST_REL(mset2[2].get_weight(),>,mset1[2].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1526 [ +  - ][ +  - ]:          7 :     TEST_REL(mset2[3].get_weight(),>,mset1[3].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1527 [ +  - ][ +  - ]:          7 :     TEST_REL(mset2[4].get_weight(),>,mset1[4].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1528                 :            : 
    1529                 :          7 :     return true;
    1530                 :            : }
    1531                 :            : 
    1532                 :            : // Regression test that OP_SCALE_WEIGHT works with LMWeight (fixed in 1.4.1).
    1533                 :          7 : DEFINE_TESTCASE(unigramlmweight8, backend) {
    1534 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata");
    1535         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
    1536 [ +  - ][ +  - ]:         14 :     Xapian::Query query("paragraph");
    1537                 :            : 
    1538         [ +  - ]:          7 :     enquire.set_query(query);
    1539         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::DIRICHLET_SMOOTHING, 2000, 0));
    1540                 :            : 
    1541         [ +  - ]:         14 :     Xapian::MSet mset1;
    1542 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
    1543 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 5);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1544                 :            : 
    1545 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
    1546         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::LMWeight(0, Xapian::Weight::DIRICHLET_SMOOTHING, 2000, 0));
    1547                 :            : 
    1548         [ +  - ]:         14 :     Xapian::MSet mset2;
    1549 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
    1550 [ +  - ][ +  - ]:          7 :     TEST_EQUAL(mset2.size(), mset1.size());
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1551 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1552 [ +  - ][ +  + ]:         42 :     for (Xapian::doccount i = 0; i < mset1.size(); ++i) {
    1553 [ +  - ][ +  - ]:         35 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1554                 :            :     }
    1555                 :            : 
    1556                 :          7 :     return true;
    1557                 :            : }
    1558                 :            : 
    1559                 :            : // Feature test for BoolWeight.
    1560                 :            : // Test exception for junk after serialised weight.
    1561                 :          1 : DEFINE_TESTCASE(boolweight1, !backend) {
    1562                 :          1 :     Xapian::BoolWeight wt;
    1563                 :            :     try {
    1564                 :          1 :         Xapian::BoolWeight t;
    1565 [ +  - ][ +  - ]:          1 :         Xapian::BoolWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
    1566                 :            :         // Make sure we actually use the weight.
    1567         [ #  # ]:          0 :         bool empty = t2->name().empty();
    1568         [ #  # ]:          0 :         delete t2;
    1569         [ #  # ]:          0 :         if (empty)
    1570 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised BoolWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
    1571 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised BoolWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
    1572 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
    1573 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("Bool") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1574                 :            :     }
    1575                 :          1 :     return true;
    1576                 :            : }
    1577                 :            : 
    1578                 :            : // Feature test for CoordWeight.
    1579                 :          7 : DEFINE_TESTCASE(coordweight1, backend) {
    1580 [ +  - ][ +  - ]:          7 :     Xapian::Enquire enquire(get_database("apitest_simpledata"));
                 [ +  - ]
    1581         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::CoordWeight());
    1582                 :            :     static const char * const terms[] = {
    1583                 :            :         "this", "line", "paragraph", "rubbish"
    1584                 :            :     };
    1585                 :            :     Xapian::Query query(Xapian::Query::OP_OR,
    1586         [ +  - ]:         14 :                         terms, terms + sizeof(terms) / sizeof(terms[0]));
    1587         [ +  - ]:          7 :     enquire.set_query(query);
    1588         [ +  - ]:         14 :     Xapian::MSet mymset1 = enquire.get_mset(0, 100);
    1589                 :            :     // CoordWeight scores 1 for each matching term, so the weight should equal
    1590                 :            :     // the number of matching terms.
    1591 [ +  - ][ +  - ]:         49 :     for (Xapian::MSetIterator i = mymset1.begin(); i != mymset1.end(); ++i) {
                 [ +  + ]
    1592                 :         42 :         Xapian::termcount matching_terms = 0;
    1593         [ +  - ]:         42 :         Xapian::TermIterator t = enquire.get_matching_terms_begin(i);
    1594         [ +  + ]:        140 :         while (t != enquire.get_matching_terms_end(i)) {
    1595                 :         98 :             ++matching_terms;
    1596         [ +  - ]:         98 :             ++t;
    1597                 :            :         }
    1598 [ +  - ][ -  + ]:         42 :         TEST_EQUAL(i.get_weight(), matching_terms);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1599                 :         49 :     }
    1600                 :            : 
    1601                 :            :     // Test with OP_SCALE_WEIGHT.
    1602 [ +  - ][ +  - ]:          7 :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, query, 15.0));
    1603         [ +  - ]:         14 :     Xapian::MSet mymset2 = enquire.get_mset(0, 100);
    1604 [ +  - ][ +  - ]:          7 :     TEST_EQUAL(mymset1.size(), mymset2.size());
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1605 [ +  - ][ +  + ]:         49 :     for (Xapian::doccount i = 0; i != mymset1.size(); ++i) {
    1606 [ +  - ][ +  - ]:         42 :         TEST_EQUAL(15.0 * mymset1[i].get_weight(), mymset2[i].get_weight());
         [ +  - ][ +  - ]
         [ -  + ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1607                 :            :     }
    1608                 :            : 
    1609                 :          7 :     return true;
    1610                 :            : }
    1611                 :            : 
    1612                 :            : // Test exception for junk after serialised weight.
    1613                 :          1 : DEFINE_TESTCASE(coordweight2, !backend) {
    1614                 :          1 :     Xapian::CoordWeight wt;
    1615                 :            :     try {
    1616                 :          1 :         Xapian::CoordWeight t;
    1617 [ +  - ][ +  - ]:          1 :         Xapian::CoordWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
    1618                 :            :         // Make sure we actually use the weight.
    1619         [ #  # ]:          0 :         bool empty = t2->name().empty();
    1620         [ #  # ]:          0 :         delete t2;
    1621         [ #  # ]:          0 :         if (empty)
    1622 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised CoordWeight with junk appended unserialised to empty name!");
         [ #  # ][ #  # ]
    1623 [ #  # ][ #  # ]:          1 :         FAIL_TEST("Serialised CoordWeight with junk appended unserialised OK");
         [ #  # ][ #  # ]
    1624 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
    1625 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("Coord") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1626                 :            :     }
    1627                 :          1 :     return true;
    1628                 :            : }
    1629                 :            : 
    1630                 :            : // Test exception for junk after serialised weight.
    1631                 :          1 : DEFINE_TESTCASE(dicecoeffweight1, !backend) {
    1632                 :          1 :     Xapian::DiceCoeffWeight wt;
    1633                 :            :     try {
    1634                 :          1 :         Xapian::DiceCoeffWeight t;
    1635 [ +  - ][ +  - ]:          1 :         Xapian::DiceCoeffWeight * t2 = t.unserialise(wt.serialise() + "X");
                 [ -  + ]
    1636                 :            :         // Make sure we actually use the weight.
    1637         [ #  # ]:          0 :         bool empty = t2->name().empty();
    1638         [ #  # ]:          0 :         delete t2;
    1639         [ #  # ]:          0 :         if (empty)
    1640 [ #  # ][ #  # ]:          0 :             FAIL_TEST("Serialised DiceCoeffWeight with junk appended"
         [ #  # ][ #  # ]
    1641                 :            :                     "unserialised to empty name!");
    1642 [ #  # ][ #  # ]:          0 :         FAIL_TEST("Serialised DiceCoeffWeight with junk appended"
         [ #  # ][ #  # ]
    1643                 :          1 :                 "unserialised OK");
    1644 [ -  + ][ +  - ]:          2 :     } catch (const Xapian::SerialisationError &e) {
    1645 [ -  + ][ -  +  :          1 :         TEST(e.get_msg().find("DiceCoeff") != string::npos);
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    1646                 :            :     }
    1647                 :          1 :     return true;
    1648                 :            : }
    1649                 :            : 
    1650                 :            : // Feature test.
    1651                 :          7 : DEFINE_TESTCASE(dicecoeffweight2, backend) {
    1652 [ +  - ][ +  - ]:          7 :     Xapian::Database db = get_database("apitest_simpledata3");
    1653         [ +  - ]:         14 :     Xapian::Enquire enquire(db);
    1654                 :            :     static const char * const terms[] = {
    1655                 :            :         "one", "three"
    1656                 :            :     };
    1657                 :            :     Xapian::Query query(Xapian::Query::OP_OR,
    1658         [ +  - ]:         14 :                         terms, terms + sizeof(terms) / sizeof(terms[0]));
    1659         [ +  - ]:          7 :     enquire.set_query(query);
    1660         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DiceCoeffWeight());
    1661                 :            : 
    1662         [ +  - ]:         14 :     Xapian::MSet mset1;
    1663 [ +  - ][ +  - ]:          7 :     mset1 = enquire.get_mset(0, 10);
    1664 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset1.size(), 4);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1665                 :            : 
    1666                 :            :     /* The weight value has been manually calculated by using the statistics
    1667                 :            :      * of the test database. */
    1668 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[0].get_weight(), 0.571428571428571);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1669 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[1].get_weight(), 0.5);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1670 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[2].get_weight(), 0.2);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1671 [ +  - ][ +  - ]:          7 :     TEST_EQUAL_DOUBLE(mset1[3].get_weight(), 0.181818181818182);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1672                 :            : 
    1673                 :            :     /* // Test with OP_SCALE_WEIGHT. */
    1674                 :            :     enquire.set_query(Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT,
    1675 [ +  - ][ +  - ]:          7 :                       query, 15.0));
    1676         [ +  - ]:          7 :     enquire.set_weighting_scheme(Xapian::DiceCoeffWeight());
    1677                 :            : 
    1678         [ +  - ]:         14 :     Xapian::MSet mset2;
    1679 [ +  - ][ +  - ]:          7 :     mset2 = enquire.get_mset(0, 10);
    1680 [ +  - ][ -  + ]:          7 :     TEST_EQUAL(mset2.size(), 4);
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1681                 :            : 
    1682 [ +  - ][ +  - ]:          7 :     TEST_NOT_EQUAL_DOUBLE(mset1[0].get_weight(), 0.0);
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1683         [ +  + ]:         28 :     for (int i = 0; i < 3; ++i) {
    1684 [ +  - ][ +  - ]:         21 :         TEST_EQUAL_DOUBLE(15.0 * mset1[i].get_weight(), mset2[i].get_weight());
         [ +  - ][ +  - ]
         [ +  - ][ -  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
    1685                 :            :     }
    1686                 :            : 
    1687                 :          7 :     return true;
    1688                 :            : }

Generated by: LCOV version 1.11