/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using NUnit.Framework; namespace Lucene.Net.Search { /// yonik /// public class QueryUtils { [Serializable] private class AnonymousClassQuery : Query { public override System.String ToString(System.String field) { return "My Whacky Query"; } override public System.Object Clone() { return null; } } private class AnonymousClassHitCollector : HitCollector { public AnonymousClassHitCollector(int[] which, Lucene.Net.Search.Scorer scorer, int[] sdoc, float maxDiff, Lucene.Net.Search.Query q, Lucene.Net.Search.IndexSearcher s) { InitBlock(which, scorer, sdoc, maxDiff, q, s); } private void InitBlock(int[] which, Lucene.Net.Search.Scorer scorer, int[] sdoc, float maxDiff, Lucene.Net.Search.Query q, Lucene.Net.Search.IndexSearcher s) { this.which = which; this.scorer = scorer; this.sdoc = sdoc; this.maxDiff = maxDiff; this.q = q; this.s = s; } private int[] which; private Lucene.Net.Search.Scorer scorer; private int[] sdoc; private float maxDiff; private Lucene.Net.Search.Query q; private Lucene.Net.Search.IndexSearcher s; public override void Collect(int doc, float score) { try { bool more = (which[0]++ & 0x02) == 0?scorer.SkipTo(sdoc[0] + 1):scorer.Next(); sdoc[0] = scorer.Doc(); float scorerScore = scorer.Score(); float scoreDiff = System.Math.Abs(score - scorerScore); scoreDiff = 0; // TODO: remove this go get LUCENE-697 // failures if (more == false || doc != sdoc[0] || scoreDiff > maxDiff) { throw new System.SystemException("ERROR matching docs:" + "\n\tscorer.more=" + more + " doc=" + sdoc[0] + " score=" + scorerScore + "\n\thitCollector.doc=" + doc + " score=" + score + "\n\t Scorer=" + scorer + "\n\t Query=" + q + "\n\t Searcher=" + s); } } catch (System.IO.IOException e) { throw new System.SystemException("", e); } } } /// Check the types of things query objects should be able to do. public static void Check(Query q) { CheckHashEquals(q); } /// check very basic hashCode and equals public static void CheckHashEquals(Query q) { Query q2 = (Query) q.Clone(); CheckEqual(q, q2); Query q3 = (Query) q.Clone(); q3.SetBoost(7.21792348f); CheckUnequal(q, q3); // test that a class check is done so that no exception is thrown // in the implementation of equals() Query whacky = new AnonymousClassQuery(); whacky.SetBoost(q.GetBoost()); CheckUnequal(q, whacky); } public static void CheckEqual(Query q1, Query q2) { Assert.AreEqual(q1.ToString(), q2.ToString()); Assert.AreEqual(q1.GetHashCode(), q2.GetHashCode()); } public static void CheckUnequal(Query q1, Query q2) { Assert.IsTrue(q1.ToString() != q2.ToString()); Assert.IsTrue(q2.ToString() != q1.ToString()); // possible this test can fail on a hash collision... if that // happens, please change test to use a different example. Assert.IsTrue(q1.GetHashCode() != q2.GetHashCode()); } /// various query sanity checks on a searcher public static void Check(Query q1, Searcher s) { try { Check(q1); if (s != null && s is IndexSearcher) { IndexSearcher is_Renamed = (IndexSearcher) s; CheckSkipTo(q1, is_Renamed); } } catch (System.IO.IOException e) { throw new System.SystemException("", e); } } /// alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc /// and ensure a hitcollector receives same docs and scores /// public static void CheckSkipTo(Query q, IndexSearcher s) { // System.out.println("Checking "+q); Weight w = q.Weight(s); Scorer scorer = w.Scorer(s.GetIndexReader()); // FUTURE: ensure scorer.doc()==-1 if (BooleanQuery.GetUseScorer14()) return ; // 1.4 doesn't support skipTo int[] which = new int[1]; int[] sdoc = new int[]{- 1}; float maxDiff = 1e-5f; s.Search(q, new AnonymousClassHitCollector(which, scorer, sdoc, maxDiff, q, s)); // make sure next call to scorer is false. Assert.IsFalse((which[0]++ & 0x02) == 0 ? scorer.SkipTo(sdoc[0] + 1) : scorer.Next()); } } }