Add DB_BACKEND_INMEMORY; deprecate InMemory::open()
[xapian.git] / xapian-bindings / csharp / SmokeTest.cs
blob5bd71725d39f294bf4ec67435b3bb3a46bdd685a
1 // Simple test that we can load the xapian module and run a simple test
2 //
3 // Copyright (C) 2004,2005,2006,2007,2008,2011,2016 Olly Betts
4 //
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.
9 //
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
18 // USA
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:
29 using Xapian;
31 class TestMatchDecider : Xapian.MatchDecider {
32 public override bool Apply(Xapian.Document doc) {
33 return (doc.GetValue(0) == "yes");
37 class SmokeTest {
38 public static void Main() {
39 try {
40 // Test the version number reporting functions give plausible
41 // results.
42 string v = "";
43 v += Xapian.Version.Major();
44 v += ".";
45 v += Xapian.Version.Minor();
46 v += ".";
47 v += Xapian.Version.Revision();
48 string v2 = Xapian.Version.String();
49 if (v != v2) {
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++.
59 doc.SetData("a\0b");
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?");
70 doc.AddTerm("XYzzy");
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);
78 db.AddDocument(doc);
79 if (db.GetDocCount() != 1) {
80 System.Environment.Exit(1);
83 if (doc.TermListCount() != 5) {
84 System.Environment.Exit(1);
86 int count = 0;
87 Xapian.TermIterator i = doc.TermListBegin();
88 while (i != doc.TermListEnd()) {
89 ++count;
90 ++i;
92 if (count != 5) {
93 System.Environment.Exit(1);
96 // Check exception handling for Xapian::DocNotFoundError.
97 try {
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.
110 try {
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
125 // here.
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#).
141 try {
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();
152 doc.SetData("Two");
153 doc.AddPosting(stem.Apply("out"), 1);
154 doc.AddPosting(stem.Apply("source"), 2);
155 doc.AddValue(0, "yes");
156 db.AddDocument(doc);
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.
178 System.GC.Collect();
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);