1 // Simple test that we can load the xapian module and run a simple test
3 // Copyright (C) 2004,2005,2006,2007,2008,2011,2016 Olly Betts
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License as
7 // published by the Free Software Foundation; either version 2 of the
8 // License, or (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
20 // The Portable.NET compiler has a bug which prevents it finding static
21 // member functions such as Xapian.Version.Major():
23 // http://savannah.gnu.org/bugs/?func=detailitem&item_id=12231
25 // The bug is fixed in Portable.NET CVS HEAD - the fix should make it
26 // into Portable.NET 0.8.2.
28 // The workaround for now is to add an explicit "using Xapian;" here:
31 class TestMatchDecider
: Xapian
.MatchDecider
{
32 public override bool Apply(Xapian
.Document doc
) {
33 return (doc
.GetValue(0) == "yes");
38 public static void Main() {
40 // Test the version number reporting functions give plausible
43 v
+= Xapian
.Version
.Major();
45 v
+= Xapian
.Version
.Minor();
47 v
+= Xapian
.Version
.Revision();
48 string v2
= Xapian
.Version
.String();
50 System
.Console
.WriteLine("Unexpected version output (" + v
+ " != " + v2
+ ")");
51 System
.Environment
.Exit(1);
54 Xapian
.Stem stem
= new Xapian
.Stem("english");
55 Xapian
.Document doc
= new Xapian
.Document();
56 // Currently SWIG doesn't generate zero-byte clean code for
57 // transferring strings between C# and C++.
60 if (doc.GetData() == "a") {
61 System.Console.WriteLine("GetData+SetData truncates at a zero byte");
62 System.Environment.Exit(1);
64 if (doc.GetData() != "a\0b") {
65 System.Console.WriteLine("GetData+SetData doesn't transparently handle a zero byte");
66 System.Environment.Exit(1);
69 doc
.SetData("is there anybody out there?");
71 doc
.AddPosting(stem
.Apply("is"), 1);
72 doc
.AddPosting(stem
.Apply("there"), 2);
73 doc
.AddPosting(stem
.Apply("anybody"), 3);
74 doc
.AddPosting(stem
.Apply("out"), 4);
75 doc
.AddPosting(stem
.Apply("there"), 5);
77 Xapian
.WritableDatabase
db("", Xapian
.DB_BACKEND_INMEMORY
);
79 if (db
.GetDocCount() != 1) {
80 System
.Environment
.Exit(1);
83 if (doc
.TermListCount() != 5) {
84 System
.Environment
.Exit(1);
87 Xapian
.TermIterator i
= doc
.TermListBegin();
88 while (i
!= doc
.TermListEnd()) {
93 System
.Environment
.Exit(1);
96 // Check exception handling for Xapian::DocNotFoundError.
98 Xapian
.Document doc2
= db
.GetDocument(2);
99 System
.Console
.WriteLine("Retrieved non-existent document: " + doc2
.ToString());
100 System
.Environment
.Exit(1);
101 } catch (System
.Exception e
) {
102 // We expect DocNotFoundError
103 if (e
.Message
.Substring(0, 16) != "DocNotFoundError") {
104 System
.Console
.WriteLine("Unexpected exception from accessing non-existent document: " + e
.Message
);
105 System
.Environment
.Exit(1);
109 // Check QueryParser parsing error.
111 Xapian
.QueryParser qp
= new Xapian
.QueryParser();
112 qp
.ParseQuery("test AND");
113 System
.Console
.WriteLine("Successfully parsed bad query");
114 System
.Environment
.Exit(1);
115 } catch (System
.Exception e
) {
116 if (e
.Message
!= "QueryParserError: Syntax: <expression> AND <expression>") {
117 System
.Console
.WriteLine("Exception string not as expected, got: '" + e
.Message
+ "'");
118 System
.Environment
.Exit(1);
123 Xapian
.QueryParser qp
= new Xapian
.QueryParser();
124 // FIXME: It would be better if the (uint) cast wasn't required
126 qp
.ParseQuery("hello world", (uint)Xapian
.QueryParser
.feature_flag
.FLAG_BOOLEAN
);
129 if (Xapian
.Query
.MatchAll
.GetDescription() != "Query(<alldocuments>)") {
130 System
.Console
.WriteLine("Unexpected Query.MatchAll.toString()");
131 System
.Environment
.Exit(1);
134 if (Xapian
.Query
.MatchNothing
.GetDescription() != "Query()") {
135 System
.Console
.WriteLine("Unexpected Query.MatchNothing.toString()");
136 System
.Environment
.Exit(1);
139 // Check that OP_ELITE_SET works (in 0.9.6 and earlier it had the
140 // wrong value in C#).
142 Xapian
.Query foo
= new Xapian
.Query(Xapian
.Query
.op
.OP_OR
, "hello", "world");
143 Xapian
.Query foo2
= new Xapian
.Query(Xapian
.Query
.op
.OP_ELITE_SET
, foo
, foo
);
144 foo
= foo2
; // Avoid "unused variable" warning.
145 } catch (System
.Exception e
) {
146 System
.Console
.WriteLine("Using OP_ELITE_SET cause exception '" + e
.Message
+ "'");
147 System
.Environment
.Exit(1);
150 // Feature test for MatchDecider.
151 doc
= new Xapian
.Document();
153 doc
.AddPosting(stem
.Apply("out"), 1);
154 doc
.AddPosting(stem
.Apply("source"), 2);
155 doc
.AddValue(0, "yes");
158 Xapian
.Query query
= new Xapian
.Query(stem
.Apply("out"));
159 Xapian
.Enquire enquire
= new Xapian
.Enquire(db
);
160 enquire
.SetQuery(query
);
161 Xapian
.MSet mset
= enquire
.GetMSet(0, 10, null, new TestMatchDecider());
162 if (mset
.Size() != 1) {
163 System
.Console
.WriteLine("MatchDecider found " + mset
.Size().ToString() + " documents, expected 1");
164 System
.Environment
.Exit(1);
166 if (mset
.GetDocId(0) != 2) {
167 System
.Console
.WriteLine("MatchDecider mset has wrong docid in");
168 System
.Environment
.Exit(1);
171 mset
= enquire
.GetMSet(0, 10);
172 for (Xapian
.MSetIterator m
= mset
.Begin(); m
!= mset
.End(); m
++) {
173 // In Xapian 1.2.6 and earlier, the iterator would become
174 // eligible for garbage collection after being advanced.
175 // It didn't actually get garbage collected often, but when
176 // it did, it caused a crash. Here we force a GC run to make
177 // this issue manifest if it is present.
179 System
.GC
.WaitForPendingFinalizers();
182 // Test setting and getting metadata
183 if (db
.GetMetadata("Foo") != "") {
184 System
.Console
.WriteLine("db.GetMetadata(\"Foo\") returned wrong value \"" + db
.GetMetadata("Foo") + "\" - expected \"\"");
185 System
.Environment
.Exit(1);
187 db
.SetMetadata("Foo", "Foo");
188 if (db
.GetMetadata("Foo") != "Foo") {
189 System
.Console
.WriteLine("db.GetMetadata(\"Foo\") returned wrong value \"" + db
.GetMetadata("Foo") + "\" - expected \"Foo\"");
190 System
.Environment
.Exit(1);
193 // Test OP_SCALE_WEIGHT and corresponding constructor
194 Xapian
.Query query4
= new Xapian
.Query(Xapian
.Query
.op
.OP_SCALE_WEIGHT
, new Xapian
.Query("foo"), 5.0);
195 if (query4
.GetDescription() != "Query(5 * foo)") {
196 System
.Console
.WriteLine("Unexpected query4.GetDescription()");
197 System
.Environment
.Exit(1);
200 } catch (System
.Exception e
) {
201 System
.Console
.WriteLine("Exception: " + e
.ToString());
202 System
.Environment
.Exit(1);