You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2012/09/23 01:04:39 UTC

svn commit: r1388918 - in /lucene.net/trunk/test: contrib/Spatial/ contrib/Spatial/BBox/ contrib/Spatial/Prefix/ contrib/Spatial/Prefix/Tree/ contrib/Spatial/Queries/ contrib/Spatial/Vector/ core/Util/

Author: synhershko
Date: Sat Sep 22 23:04:38 2012
New Revision: 1388918

URL: http://svn.apache.org/viewvc?rev=1388918&view=rev
Log:
Tests catch-up

Added:
    lucene.net/trunk/test/contrib/Spatial/CheckHits.cs
    lucene.net/trunk/test/contrib/Spatial/DistanceStrategyTest.cs
Removed:
    lucene.net/trunk/test/contrib/Spatial/Various.cs
Modified:
    lucene.net/trunk/test/contrib/Spatial/BBox/TestBBoxStrategy.cs
    lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Tests.csproj
    lucene.net/trunk/test/contrib/Spatial/PortedSolr3Test.cs
    lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs
    lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs
    lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs
    lucene.net/trunk/test/contrib/Spatial/Queries/SpatialArgsParserTest.cs
    lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs
    lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs
    lucene.net/trunk/test/contrib/Spatial/Vector/TestTwoDoublesStrategy.cs
    lucene.net/trunk/test/core/Util/LuceneTestCase.cs

Modified: lucene.net/trunk/test/contrib/Spatial/BBox/TestBBoxStrategy.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/BBox/TestBBoxStrategy.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/BBox/TestBBoxStrategy.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/BBox/TestBBoxStrategy.cs Sat Sep 22 23:04:38 2012
@@ -18,6 +18,7 @@
 using Lucene.Net.Spatial.BBox;
 using Spatial4n.Core.Context;
 using NUnit.Framework;
+using Spatial4n.Core.Shapes;
 
 namespace Lucene.Net.Contrib.Spatial.Test.BBox
 {
@@ -27,10 +28,15 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		public override void SetUp()
 		{
 			base.SetUp();
-			this.ctx = SpatialContext.GEO_KM;
+			this.ctx = SpatialContext.GEO;
 			this.strategy = new BBoxStrategy(ctx, "bbox");
 		}
 
+        protected override Shape convertShapeFromGetDocuments(Spatial4n.Core.Shapes.Shape shape)
+        {
+            return shape.GetBoundingBox();
+        }
+
 		[Test]
 		public void testBasicOperaions()
 		{
@@ -42,18 +48,18 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		[Test]
 		public void testStatesBBox()
 		{
-			getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
+            getAddAndVerifyIndexedDocuments(DATA_STATES_BBOX);
 
-			executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
-			executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
+            executeQueries(SpatialMatchConcern.FILTER, QTEST_States_IsWithin_BBox);
+            executeQueries(SpatialMatchConcern.FILTER, QTEST_States_Intersects_BBox);
 		}
 
 		[Test]
-		public void testCitiesWithinBBox()
+		public void testCitiesIntersectsBBox()
 		{
 			getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
 
-			executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox);
+			executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
 		}
 	}
 }

Added: lucene.net/trunk/test/contrib/Spatial/CheckHits.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/CheckHits.cs?rev=1388918&view=auto
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/CheckHits.cs (added)
+++ lucene.net/trunk/test/contrib/Spatial/CheckHits.cs Sat Sep 22 23:04:38 2012
@@ -0,0 +1,240 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+
+namespace Lucene.Net.Contrib.Spatial.Test
+{
+    /// <summary>
+    /// Utility class for asserting expected hits in tests.
+    /// 
+    /// Taken from apache.lucene.search
+    /// </summary>
+    public class CheckHits : LuceneTestCase
+    {
+        /**
+* Asserts that the explanation value for every document matching a
+* query corresponds with the true score.  Optionally does "deep" 
+* testing of the explanation details.
+*
+* @see ExplanationAsserter
+* @param query the query to test
+* @param searcher the searcher to test the query against
+* @param defaultFieldName used for displaing the query in assertion messages
+* @param deep indicates whether a deep comparison of sub-Explanation details should be executed
+*/
+        public static void checkExplanations(Query query,
+                                             String defaultFieldName,
+                                             IndexSearcher searcher,
+                                             bool deep = false)
+        {
+
+            searcher.Search(query,
+                            new ExplanationAsserter
+                                (query, defaultFieldName, searcher, deep));
+
+        }
+
+        public class ExplanationAsserter : Collector
+        {
+            /**
+ * Some explains methods calculate their values though a slightly
+ * different  order of operations from the actual scoring method ...
+ * this allows for a small amount of relative variation
+ */
+            public static float EXPLAIN_SCORE_TOLERANCE_DELTA = 0.001f;
+
+            /**
+             * In general we use a relative epsilon, but some tests do crazy things
+             * like boost documents with 0, creating tiny tiny scores where the
+             * relative difference is large but the absolute difference is tiny.
+             * we ensure the the epsilon is always at least this big.
+             */
+            public static float EXPLAIN_SCORE_TOLERANCE_MINIMUM = 1e-6f;
+
+            private Query q;
+            private IndexSearcher s;
+            private String d;
+            private bool deep;
+
+            private Scorer scorer;
+            private int @base = 0;
+
+            /** Constructs an instance which does shallow tests on the Explanation */
+
+            public ExplanationAsserter(Query q, String defaultFieldName, IndexSearcher s)
+                : this(q, defaultFieldName, s, false)
+            {
+            }
+
+            public ExplanationAsserter(Query q, String defaultFieldName, IndexSearcher s, bool deep)
+            {
+                this.q = q;
+                this.s = s;
+                this.d = q.ToString(defaultFieldName);
+                this.deep = deep;
+            }
+
+            public override void SetScorer(Scorer scorer)
+            {
+                this.scorer = scorer;
+            }
+
+            public override void Collect(int doc)
+            {
+                Explanation exp = null;
+                doc = doc + @base;
+                try
+                {
+                    exp = s.Explain(q, doc);
+                }
+                catch (IOException e)
+                {
+                    throw new Exception
+                        ("exception in hitcollector of [[" + d + "]] for #" + doc, e);
+                }
+
+                assertNotNull("Explanation of [[" + d + "]] for #" + doc + " is null", exp);
+                verifyExplanation(d, doc, scorer.Score(), deep, exp);
+                assertTrue("Explanation of [[" + d + "]] for #" + doc +
+                                           " does not indicate match: " + exp.ToString(), exp.IsMatch);
+            }
+
+            public override void SetNextReader(IndexReader reader, int docBase)
+            {
+                @base = docBase;
+            }
+
+            public override bool AcceptsDocsOutOfOrder
+            {
+                get { return true; }
+            }
+
+            /** 
+ * Assert that an explanation has the expected score, and optionally that its
+ * sub-details max/sum/factor match to that score.
+ *
+ * @param q String representation of the query for assertion messages
+ * @param doc Document ID for assertion messages
+ * @param score Real score value of doc with query q
+ * @param deep indicates whether a deep comparison of sub-Explanation details should be executed
+ * @param expl The Explanation to match against score
+ */
+            public static void verifyExplanation(String q,
+                                                 int doc,
+                                                 float score,
+                                                 bool deep,
+                                                 Explanation expl)
+            {
+                float value = expl.Value;
+                assertEquals(q + ": score(doc=" + doc + ")=" + score +
+                    " != explanationScore=" + value + " Explanation: " + expl,
+                    score, value, explainToleranceDelta(score, value));
+
+                if (!deep) return;
+
+                var detail = expl.GetDetails();
+                // TODO: can we improve this entire method? its really geared to work only with TF/IDF
+                if (expl.Description.EndsWith("computed from:"))
+                {
+                    return; // something more complicated.
+                }
+                if (detail != null)
+                {
+                    if (detail.Length == 1)
+                    {
+                        // simple containment, unless its a freq of: (which lets a query explain how the freq is calculated), 
+                        // just verify contained expl has same score
+                        if (!expl.Description.EndsWith("with freq of:"))
+                            verifyExplanation(q, doc, score, deep, detail[0]);
+                    }
+                    else
+                    {
+                        // explanation must either:
+                        // - end with one of: "product of:", "sum of:", "max of:", or
+                        // - have "max plus <x> times others" (where <x> is float).
+                        float x = 0;
+                        String descr = expl.Description.ToLowerInvariant();
+                        bool productOf = descr.EndsWith("product of:");
+                        bool sumOf = descr.EndsWith("sum of:");
+                        bool maxOf = descr.EndsWith("max of:");
+                        bool maxTimesOthers = false;
+                        if (!(productOf || sumOf || maxOf))
+                        {
+                            // maybe 'max plus x times others'
+                            int k1 = descr.IndexOf("max plus ");
+                            if (k1 >= 0)
+                            {
+                                k1 += "max plus ".Length;
+                                int k2 = descr.IndexOf(" ", k1);
+                                try
+                                {
+                                    x = float.Parse(descr.Substring(k1, k2).Trim());
+                                    if (descr.Substring(k2).Trim().Equals("times others of:"))
+                                    {
+                                        maxTimesOthers = true;
+                                    }
+                                }
+                                catch (FormatException e)
+                                {
+                                }
+                            }
+                        }
+                        // TODO: this is a TERRIBLE assertion!!!!
+                        assertTrue(
+                            q + ": multi valued explanation description=\"" + descr
+                            + "\" must be 'max of plus x times others' or end with 'product of'"
+                            + " or 'sum of:' or 'max of:' - " + expl,
+                            productOf || sumOf || maxOf || maxTimesOthers);
+                        float sum = 0;
+                        float product = 1;
+                        float max = 0;
+                        for (int i = 0; i < detail.Length; i++)
+                        {
+                            float dval = detail[i].Value;
+                            verifyExplanation(q, doc, dval, deep, detail[i]);
+                            product *= dval;
+                            sum += dval;
+                            max = Math.Max(max, dval);
+                        }
+                        float combined = 0;
+                        if (productOf)
+                        {
+                            combined = product;
+                        }
+                        else if (sumOf)
+                        {
+                            combined = sum;
+                        }
+                        else if (maxOf)
+                        {
+                            combined = max;
+                        }
+                        else if (maxTimesOthers)
+                        {
+                            combined = max + x * (sum - max);
+                        }
+                        else
+                        {
+                            assertTrue("should never get here!", false);
+                        }
+                        assertEquals(q + ": actual subDetails combined==" + combined +
+                            " != value=" + value + " Explanation: " + expl,
+                            combined, value, explainToleranceDelta(combined, value));
+                    }
+                }
+            }
+
+            /** returns a reasonable epsilon for comparing two floats,
+   *  where minor differences are acceptable such as score vs. explain */
+            public static float explainToleranceDelta(float f1, float f2)
+            {
+                return Math.Max(EXPLAIN_SCORE_TOLERANCE_MINIMUM, Math.Max(Math.Abs(f1), Math.Abs(f2)) * EXPLAIN_SCORE_TOLERANCE_DELTA);
+            }
+        }
+    }
+}

Modified: lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Tests.csproj
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Tests.csproj?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Tests.csproj (original)
+++ lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Tests.csproj Sat Sep 22 23:04:38 2012
@@ -104,8 +104,9 @@
     <Reference Include="nunit.framework">
       <HintPath>..\..\..\lib\NUnit.org\NUnit\2.5.9\bin\net-2.0\framework\nunit.framework.dll</HintPath>
     </Reference>
-    <Reference Include="Spatial4n.Core">
-      <HintPath>..\..\..\lib\Spatial4n\$(Framework)\Spatial4n.Core.dll</HintPath>
+    <Reference Include="Spatial4n.Core.NTS, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9f9456e1ca16d45e, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\build\bin\contrib\Spatial\Debug\NET40\Spatial4n.Core.NTS.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Condition="'$(Framework)' == 'NET35'" Include="System.Core" />
@@ -118,7 +119,9 @@
       <Link>Paths.cs</Link>
     </Compile>
     <Compile Include="BBox\TestBBoxStrategy.cs" />
+    <Compile Include="CheckHits.cs" />
     <Compile Include="Compatibility\TermsFilterTest.cs" />
+    <Compile Include="DistanceStrategyTest.cs" />
     <Compile Include="PortedSolr3Test.cs" />
     <Compile Include="Prefix\TestRecursivePrefixTreeStrategy.cs" />
     <Compile Include="Prefix\TestTermQueryPrefixGridStrategy.cs" />
@@ -130,7 +133,6 @@
     <Compile Include="SpatialTestQuery.cs" />
     <Compile Include="StrategyTestCase.cs" />
     <Compile Include="TestTestFramework.cs" />
-    <Compile Include="Various.cs" />
     <Compile Include="Vector\TestTwoDoublesStrategy.cs" />
   </ItemGroup>
   <ItemGroup>

Added: lucene.net/trunk/test/contrib/Spatial/DistanceStrategyTest.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/DistanceStrategyTest.cs?rev=1388918&view=auto
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/DistanceStrategyTest.cs (added)
+++ lucene.net/trunk/test/contrib/Spatial/DistanceStrategyTest.cs Sat Sep 22 23:04:38 2012
@@ -0,0 +1,114 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Lucene.Net.Documents;
+using Lucene.Net.Spatial;
+using Lucene.Net.Spatial.BBox;
+using Lucene.Net.Spatial.Prefix;
+using Lucene.Net.Spatial.Prefix.Tree;
+using Lucene.Net.Spatial.Vector;
+using NUnit.Framework;
+using Spatial4n.Core.Context;
+using Spatial4n.Core.Shapes;
+
+namespace Lucene.Net.Contrib.Spatial.Test
+{
+    public class DistanceStrategyTest : StrategyTestCase
+    {
+        public class TestValuesProvider
+        {
+            public IEnumerable<Param> ParamsProvider()
+            {
+                var ctorArgs = new List<Param>();
+
+                SpatialContext ctx = SpatialContext.GEO;
+                SpatialPrefixTree grid;
+                SpatialStrategy strategy;
+
+                grid = new QuadPrefixTree(ctx, 25);
+                strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
+                ctorArgs.Add(new Param(strategy));
+
+                grid = new GeohashPrefixTree(ctx, 12);
+                strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
+                ctorArgs.Add(new Param(strategy));
+
+                strategy = new TwoDoublesStrategy(ctx, "twodoubles");
+                ctorArgs.Add(new Param(strategy));
+
+                strategy = new BBoxStrategy(ctx, "bbox");
+                ctorArgs.Add(new Param(strategy));
+
+                return ctorArgs;
+            }
+        }
+
+        public class Param
+        {
+            public readonly SpatialStrategy strategy;
+
+            public Param(SpatialStrategy strategy) { this.strategy = strategy; }
+
+            public override String ToString()
+            {
+                return strategy.GetFieldName();
+            }
+        }
+
+        //  private String fieldName;
+
+        public void Init(Param param)
+        {
+            SpatialStrategy strategy = param.strategy;
+            this.ctx = strategy.GetSpatialContext();
+            this.strategy = strategy;
+        }
+
+        [Test]
+        public void testDistanceOrder([ValueSource(typeof(TestValuesProvider), "ParamsProvider")] Param p)
+        {
+            Init(p);
+
+            adoc("100", ctx.MakePoint(2, 1));
+            adoc("101", ctx.MakePoint(-1, 4));
+            adoc("103", (Shape)null);//test score for nothing
+            commit();
+            //FYI distances are in docid order
+            checkDistValueSource("3,4", 2.8274937f, 5.0898066f, 180f);
+            checkDistValueSource("4,0", 3.6043684f, 0.9975641f, 180f);
+        }
+
+        [Test]
+        public void testRecipScore([ValueSource(typeof(TestValuesProvider), "ParamsProvider")] Param p)
+        {
+            Init(p);
+
+            Point p100 = ctx.MakePoint(2, 1);
+            adoc("100", p100);
+            Point p101 = ctx.MakePoint(-1, 4);
+            adoc("101", p101);
+            adoc("103", (Shape)null); //test score for nothing
+            commit();
+
+            double dist = ctx.GetDistCalc().Distance(p100, p101);
+            Shape queryShape = ctx.MakeCircle(2.01, 0.99, dist);
+            checkValueSource(strategy.MakeRecipDistanceValueSource(queryShape),
+                             new float[] { 1.00f, 0.10f, 0f }, 0.09f);
+        }
+
+        protected override Document newDoc(String id, Shape shape)
+        {
+            //called by adoc().  Make compatible with BBoxStrategy.
+            if (shape != null && strategy is BBoxStrategy)
+                shape = ctx.MakeRectangle(shape.GetCenter(), shape.GetCenter());
+            return base.newDoc(id, shape);
+        }
+
+        void checkDistValueSource(String ptStr, params float[] distances)
+        {
+            Point pt = (Point)ctx.ReadShape(ptStr);
+            checkValueSource(strategy.MakeDistanceValueSource(pt), distances, 1.0e-4f);
+        }
+    }
+}

Modified: lucene.net/trunk/test/contrib/Spatial/PortedSolr3Test.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/PortedSolr3Test.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/PortedSolr3Test.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/PortedSolr3Test.cs Sat Sep 22 23:04:38 2012
@@ -17,14 +17,16 @@
 
 using System;
 using System.Collections.Generic;
-using Lucene.Net.Documents;
 using Lucene.Net.Search;
 using Lucene.Net.Spatial;
 using Lucene.Net.Spatial.Prefix;
 using Lucene.Net.Spatial.Prefix.Tree;
 using Lucene.Net.Spatial.Queries;
+using Lucene.Net.Spatial.Vector;
 using NUnit.Framework;
 using Spatial4n.Core.Context;
+using Spatial4n.Core.Distance;
+using Spatial4n.Core.Io;
 using Spatial4n.Core.Shapes;
 
 namespace Lucene.Net.Contrib.Spatial.Test
@@ -32,214 +34,162 @@ namespace Lucene.Net.Contrib.Spatial.Tes
    /**
 	* Based off of Solr 3's SpatialFilterTest.
 	*/
-	public class PortedSolr3Test : StrategyTestCase
-	{
-		public class TestValuesProvider
-		{
-			public List<Param> dataList = new List<Param>();
-
-			public IEnumerable<Param> ParamsProvider()
-			{
-				var ctorArgs = new List<Param>();
-
-				SpatialContext ctx = SpatialContext.GEO;
-
-				SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 12);
-				SpatialStrategy strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash");
-				ctorArgs.Add(new Param(strategy, "recursive_geohash"));
-
-				grid = new QuadPrefixTree(ctx, 25);
-				strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
-				ctorArgs.Add(new Param(strategy, "recursive_quad"));
-
-				grid = new GeohashPrefixTree(ctx, 12);
-				strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
-				ctorArgs.Add(new Param(strategy, "termquery_geohash"));
-
-				return ctorArgs;
-			}
-		}
-
-		public class Param
-		{
-			public readonly SpatialStrategy strategy;
-			public readonly String description;
-
-			public Param(SpatialStrategy strategy, String description)
-			{
-				this.strategy = strategy;
-				this.description = description;
-			}
-
-			public override String ToString()
-			{
-				return description;
-			}
-		}
-
-		Random random;
-
-		private void setupDocs()
-		{
-			random = NewRandom();
-			deleteAll();
-			adoc("1", "32.7693246, -79.9289094");
-			adoc("2", "33.7693246, -80.9289094");
-			adoc("3", "-32.7693246, 50.9289094");
-			adoc("4", "-50.7693246, 60.9289094");
-			adoc("5", "0,0");
-			adoc("6", "0.1,0.1");
-			adoc("7", "-0.1,-0.1");
-			adoc("8", "0,179.9");
-			adoc("9", "0,-179.9");
-			adoc("10", "89.9,50");
-			adoc("11", "89.9,-130");
-			adoc("12", "-89.9,50");
-			adoc("13", "-89.9,-130");
-			commit();
-		}
-
-		[Test, Sequential]
-		public void testIntersections([ValueSourceAttribute(typeof(TestValuesProvider), "ParamsProvider")] Param p)
-		{
-			this.ctx = p.strategy.GetSpatialContext();
-			this.strategy = p.strategy;
 
-			setupDocs();
-			//Try some edge cases
+    public class PortedSolr3Test : StrategyTestCase
+    {
+        public class TestValuesProvider
+        {
+            public List<Param> dataList = new List<Param>();
+
+            public IEnumerable<Param> ParamsProvider()
+            {
+                var ctorArgs = new List<Param>();
+
+                SpatialContext ctx = SpatialContext.GEO;
+
+                SpatialPrefixTree grid = new GeohashPrefixTree(ctx, 12);
+                SpatialStrategy strategy = new RecursivePrefixTreeStrategy(grid, "recursive_geohash");
+                ctorArgs.Add(new Param(strategy));
+
+                grid = new QuadPrefixTree(ctx, 25);
+                strategy = new RecursivePrefixTreeStrategy(grid, "recursive_quad");
+                ctorArgs.Add(new Param(strategy));
+
+                grid = new GeohashPrefixTree(ctx, 12);
+                strategy = new TermQueryPrefixTreeStrategy(grid, "termquery_geohash");
+                ctorArgs.Add(new Param(strategy));
+
+                strategy = new TwoDoublesStrategy(ctx, "twodoubles");
+                ctorArgs.Add(new Param(strategy));
+
+                return ctorArgs;
+            }
+        }
+
+        public class Param
+        {
+            public readonly SpatialStrategy strategy;
+
+            public Param(SpatialStrategy strategy) { this.strategy = strategy; }
+
+            public override String ToString()
+            {
+                return strategy.GetFieldName();
+            }
+        }
+
+        private Random random;
+
+        private void setupDocs()
+        {
+            random = NewRandom();
+            deleteAll();
+            adoc("1", "32.7693246, -79.9289094");
+            adoc("2", "33.7693246, -80.9289094");
+            adoc("3", "-32.7693246, 50.9289094");
+            adoc("4", "-50.7693246, 60.9289094");
+            adoc("5", "0,0");
+            adoc("6", "0.1,0.1");
+            adoc("7", "-0.1,-0.1");
+            adoc("8", "0,179.9");
+            adoc("9", "0,-179.9");
+            adoc("10", "89.9,50");
+            adoc("11", "89.9,-130");
+            adoc("12", "-89.9,50");
+            adoc("13", "-89.9,-130");
+            commit();
+        }
+
+        [Test, Sequential]
+        public void testIntersections([ValueSourceAttribute(typeof (TestValuesProvider), "ParamsProvider")] Param p)
+        {
+            this.ctx = p.strategy.GetSpatialContext();
+            this.strategy = p.strategy;
+
+            setupDocs();
+            //Try some edge cases
             //NOTE: 2nd arg is distance in kilometers
-			checkHitsCircle("1,1", 175, 3, 5, 6, 7);
-			checkHitsCircle("0,179.8", 200, 2, 8, 9);
-			checkHitsCircle("89.8, 50", 200, 2, 10, 11); //this goes over the north pole
-			checkHitsCircle("-89.8, 50", 200, 2, 12, 13); //this goes over the south pole
-			//try some normal cases
-			checkHitsCircle("33.0,-80.0", 300, 2);
-			//large distance
-			checkHitsCircle("1,1", 5000, 3, 5, 6, 7);
-			//Because we are generating a box based on the west/east longitudes and the south/north latitudes, which then
-			//translates to a range query, which is slightly more inclusive.  Thus, even though 0.0 is 15.725 kms away,
-			//it will be included, b/c of the box calculation.
-			checkHitsBBox("0.1,0.1", 15, 2, 5, 6);
-			//try some more
-			deleteAll();
-			adoc("14", "0,5");
-			adoc("15", "0,15");
-			//3000KM from 0,0, see http://www.movable-type.co.uk/scripts/latlong.html
-			adoc("16", "18.71111,19.79750");
-			adoc("17", "44.043900,-95.436643");
-			commit();
-
-			checkHitsCircle("0,0", 1000, 1, 14);
-			checkHitsCircle("0,0", 2000, 2, 14, 15);
-			checkHitsBBox("0,0", 3000, 3, 14, 15, 16);
-			checkHitsCircle("0,0", 3001, 3, 14, 15, 16);
-			checkHitsCircle("0,0", 3000.1, 3, 14, 15, 16);
-
-			//really fine grained distance and reflects some of the vagaries of how we are calculating the box
-			checkHitsCircle("43.517030,-96.789603", 109, 0);
-
-			// falls outside of the real distance, but inside the bounding box
-			checkHitsCircle("43.517030,-96.789603", 110, 0);
-			checkHitsBBox("43.517030,-96.789603", 110, 1, 17);
-		}
-
-		/**
-		 * This test is similar to a Solr 3 spatial test.
-		 */
-		[Test, Sequential]
-		public void testDistanceOrder([ValueSourceAttribute(typeof(TestValuesProvider), "ParamsProvider")] Param p)
-		{
-			this.ctx = p.strategy.GetSpatialContext();
-			this.strategy = p.strategy;
-
-			adoc("100", "1,2");
-			adoc("101", "4,-1");
-			commit();
-
-			//query closer to #100
-			checkHitsOrdered("Intersects(Circle(3,4 d=1000))", "101", "100");
-			//query closer to #101
-			checkHitsOrdered("Intersects(Circle(4,0 d=1000))", "100", "101");
-		}
-
-		private void checkHitsOrdered(String spatialQ, params String[] ids)
-		{
-			SpatialArgs args = this.argsParser.Parse(spatialQ, ctx);
-			Query query = strategy.MakeQuery(args);
-			SearchResults results = executeQuery(query, 100);
-			var resultIds = new String[results.numFound];
-			int i = 0;
-			foreach (SearchResult result in results.results)
-			{
-				resultIds[i++] = result.document.Get("id");
-			}
-
-			Assert.AreEqual(ids, resultIds, "order matters");
-		}
-
-		//---- these are similar to Solr test methods
-
-		private void adoc(String idStr, String shapeStr)
-		{
-			Shape shape = ctx.ReadShape(shapeStr);
-			addDocument(newDoc(idStr, shape));
-		}
-
-		//@SuppressWarnings("unchecked")
-		private Document newDoc(String id, Shape shape)
-		{
-			Document doc = new Document();
-			doc.Add(new Field("id", id, Field.Store.YES, Field.Index.ANALYZED));
-			foreach (var f in strategy.CreateIndexableFields(shape))
-			{
-				doc.Add(f);
-			}
-			if (storeShape)
-				doc.Add(new Field(strategy.GetFieldName(), ctx.ToString(shape), Field.Store.YES, Field.Index.NO));
-			return doc;
-		}
-
-		private void checkHitsCircle(String ptStr, double dist, int assertNumFound, params int[] assertIds)
-		{
-			_checkHits(SpatialOperation.Intersects, ptStr, dist, assertNumFound, assertIds);
-		}
-
-		private void checkHitsBBox(String ptStr, double dist, int assertNumFound, params int[] assertIds)
-		{
-			_checkHits(SpatialOperation.BBoxIntersects, ptStr, dist, assertNumFound, assertIds);
-		}
-
-		//@SuppressWarnings("unchecked")
-		private void _checkHits(SpatialOperation op, String ptStr, double dist, int assertNumFound, params int[] assertIds)
-		{
-			Point pt = (Point) ctx.ReadShape(ptStr);
-			Shape shape = ctx.MakeCircle(pt, dist);
-
-			SpatialArgs args = new SpatialArgs(op, shape);
-			//args.setDistPrecision(0.025);
-			Query query;
-			if (random.NextDouble() > 0.5)
-			{
-				query = strategy.MakeQuery(args);
-			}
-			else
-			{
-				query = new FilteredQuery(new MatchAllDocsQuery(), strategy.MakeFilter(args));
-			}
-			SearchResults results = executeQuery(query, 100);
-			Assert.AreEqual(assertNumFound, results.numFound, "" + shape);
-			if (assertIds != null)
-			{
-				var resultIds = new HashSet<int>();
-				foreach (SearchResult result in results.results)
-				{
-					resultIds.Add(int.Parse(result.document.Get("id")));
-				}
-				foreach (int assertId in assertIds)
-				{
-					Assert.True(resultIds.Contains(assertId), "has " + assertId);
-				}
-			}
-		}
-	}
+            checkHitsCircle("1,1", 175, 3, 5, 6, 7);
+            checkHitsCircle("0,179.8", 200, 2, 8, 9);
+            checkHitsCircle("89.8, 50", 200, 2, 10, 11); //this goes over the north pole
+            checkHitsCircle("-89.8, 50", 200, 2, 12, 13); //this goes over the south pole
+            //try some normal cases
+            checkHitsCircle("33.0,-80.0", 300, 2);
+            //large distance
+            checkHitsCircle("1,1", 5000, 3, 5, 6, 7);
+            //Because we are generating a box based on the west/east longitudes and the south/north latitudes, which then
+            //translates to a range query, which is slightly more inclusive.  Thus, even though 0.0 is 15.725 kms away,
+            //it will be included, b/c of the box calculation.
+            checkHitsBBox("0.1,0.1", 15, 2, 5, 6);
+            //try some more
+            deleteAll();
+            adoc("14", "0,5");
+            adoc("15", "0,15");
+            //3000KM from 0,0, see http://www.movable-type.co.uk/scripts/latlong.html
+            adoc("16", "18.71111,19.79750");
+            adoc("17", "44.043900,-95.436643");
+            commit();
+
+            checkHitsCircle("0,0", 1000, 1, 14);
+            checkHitsCircle("0,0", 2000, 2, 14, 15);
+            checkHitsBBox("0,0", 3000, 3, 14, 15, 16);
+            checkHitsCircle("0,0", 3001, 3, 14, 15, 16);
+            checkHitsCircle("0,0", 3000.1, 3, 14, 15, 16);
+
+            //really fine grained distance and reflects some of the vagaries of how we are calculating the box
+            checkHitsCircle("43.517030,-96.789603", 109, 0);
+
+            // falls outside of the real distance, but inside the bounding box
+            checkHitsCircle("43.517030,-96.789603", 110, 0);
+            checkHitsBBox("43.517030,-96.789603", 110, 1, 17);
+        }
+
+        //---- these are similar to Solr test methods
+
+        private void checkHitsCircle(String ptStr, double distKM, int assertNumFound, params int[] assertIds)
+        {
+            _checkHits(false, ptStr, distKM, assertNumFound, assertIds);
+        }
+
+        private void checkHitsBBox(String ptStr, double distKM, int assertNumFound, params int[] assertIds)
+        {
+            _checkHits(true, ptStr, distKM, assertNumFound, assertIds);
+        }
+
+        private void _checkHits(bool bbox, String ptStr, double distKM, int assertNumFound, params int[] assertIds)
+        {
+            SpatialOperation op = SpatialOperation.Intersects;
+            Point pt = (Point) new ShapeReadWriter(ctx).ReadShape(ptStr);
+            double distDEG = DistanceUtils.Dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+            Shape shape = ctx.MakeCircle(pt, distDEG);
+            if (bbox)
+                shape = shape.GetBoundingBox();
+
+            SpatialArgs args = new SpatialArgs(op, shape);
+            //args.setDistPrecision(0.025);
+            Query query;
+            if (random.NextDouble() > 0.5)
+            {
+                query = strategy.MakeQuery(args);
+            }
+            else
+            {
+                query = new FilteredQuery(new MatchAllDocsQuery(), strategy.MakeFilter(args));
+            }
+            SearchResults results = executeQuery(query, 100);
+            assertEquals("" + shape, assertNumFound, results.numFound);
+            if (assertIds != null)
+            {
+                var resultIds = new HashSet<int>();
+                foreach (var result in results.results)
+                {
+                    resultIds.Add(int.Parse(result.document.Get("id")));
+                }
+                foreach (int assertId in assertIds)
+                {
+                    assertTrue("has " + assertId, resultIds.Contains(assertId));
+                }
+            }
+        }
+    }
 }
\ No newline at end of file

Modified: lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs Sat Sep 22 23:04:38 2012
@@ -30,32 +30,32 @@ using Spatial4n.Core.Util;
 
 namespace Lucene.Net.Contrib.Spatial.Test.Prefix
 {
-	public class TestRecursivePrefixTreeStrategy : StrategyTestCase
-	{
-		private int maxLength;
-
-		//Tests should call this first.
-		private void init(int maxLength)
-		{
-			this.maxLength = maxLength;
-			this.ctx = SpatialContext.GEO;
-			var grid = new GeohashPrefixTree(ctx, maxLength);
-			this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
-		}
-
-		[Test]
-		public void testFilterWithVariableScanLevel()
-		{
-			init(GeohashPrefixTree.GetMaxLevelsPossible());
-			getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-
-			//execute queries for each prefix grid scan level
-			for (int i = 0; i <= maxLength; i++)
-			{
-				((RecursivePrefixTreeStrategy)strategy).SetPrefixGridScanLevel(i);
-				executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox);
-			}
-		}
+    public class TestRecursivePrefixTreeStrategy : StrategyTestCase
+    {
+        private int maxLength;
+
+        //Tests should call this first.
+        private void init(int maxLength)
+        {
+            this.maxLength = maxLength;
+            this.ctx = SpatialContext.GEO;
+            var grid = new GeohashPrefixTree(ctx, maxLength);
+            this.strategy = new RecursivePrefixTreeStrategy(grid, GetType().Name);
+        }
+
+        [Test]
+        public void testFilterWithVariableScanLevel()
+        {
+            init(GeohashPrefixTree.GetMaxLevelsPossible());
+            getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+
+            //execute queries for each prefix grid scan level
+            for (int i = 0; i <= maxLength; i++)
+            {
+                ((RecursivePrefixTreeStrategy) strategy).SetPrefixGridScanLevel(i);
+                executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
+            }
+        }
 
         [Test]
         public void testOneMeterPrecision()
@@ -63,7 +63,8 @@ namespace Lucene.Net.Contrib.Spatial.Tes
             init(GeohashPrefixTree.GetMaxLevelsPossible());
             GeohashPrefixTree grid = (GeohashPrefixTree) ((RecursivePrefixTreeStrategy) strategy).GetGrid();
             //DWS: I know this to be true.  11 is needed for one meter
-            assertEquals(11, grid.GetLevelForDistance(ctx.GetDistCalc().DistanceToDegrees(0.001)));
+            double degrees = DistanceUtils.Dist2Degrees(0.001, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+            assertEquals(11, grid.GetLevelForDistance(degrees));
         }
 
         [Test]
@@ -77,8 +78,11 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 
             Point qPt = ctx.MakePoint(2.4632387000000335, 48.6003516);
 
+            double KM2DEG = DistanceUtils.Dist2Degrees(1, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+            double DEG2KM = 1/KM2DEG;
+
             const double DIST = 35.75; //35.7499...
-            assertEquals(DIST, ctx.GetDistCalc().Distance(iPt, qPt), 0.001);
+            assertEquals(DIST, ctx.GetDistCalc().Distance(iPt, qPt)*DEG2KM, 0.001);
 
             //distErrPct will affect the query shape precision. The indexed precision
             // was set to nearly zilch via init(GeohashPrefixTree.getMaxLevelsPossible());
@@ -86,91 +90,90 @@ namespace Lucene.Net.Contrib.Spatial.Tes
             const double distMult = 1 + distErrPct;
 
             assertTrue(35.74*distMult >= DIST);
-            checkHits(q(qPt, 35.74, distErrPct), 1, null);
+            checkHits(q(qPt, 35.74*KM2DEG, distErrPct), 1, null);
 
             assertTrue(30*distMult < DIST);
-            checkHits(q(qPt, 30, distErrPct), 0, null);
+            checkHits(q(qPt, 30*KM2DEG, distErrPct), 0, null);
 
             assertTrue(33*distMult < DIST);
-            checkHits(q(qPt, 33, distErrPct), 0, null);
+            checkHits(q(qPt, 33*KM2DEG, distErrPct), 0, null);
 
             assertTrue(34*distMult < DIST);
-            checkHits(q(qPt, 34, distErrPct), 0, null);
+            checkHits(q(qPt, 34*KM2DEG, distErrPct), 0, null);
         }
 
-	    [Test]
-		public void geohashRecursiveRandom()
-		{
-			init(12);
-			var random = NewRandom();
-
-			//1. Iterate test with the cluster at some worldly point of interest
-            var clusterCenters = new Point[] { ctx.MakePoint(-180, 0), ctx.MakePoint(0, 90), ctx.MakePoint(0, -90) };
-			foreach (var clusterCenter in clusterCenters)
-			{
-				//2. Iterate on size of cluster (a really small one and a large one)
-				String hashCenter = GeohashUtils.EncodeLatLon(clusterCenter.GetY(), clusterCenter.GetX(), maxLength);
-				//calculate the number of degrees in the smallest grid box size (use for both lat & lon)
-				String smallBox = hashCenter.Substring(0, hashCenter.Length - 1);//chop off leaf precision
-				Rectangle clusterDims = GeohashUtils.DecodeBoundary(smallBox, ctx);
-				double smallDegrees = Math.Max(clusterDims.GetMaxX() - clusterDims.GetMinX(), clusterDims.GetMaxY() - clusterDims.GetMinY());
-				Assert.IsTrue(smallDegrees < 1);
-				const double largeDegrees = 20d; //good large size; don't use >=45 for this test code to work
-				double[] sideDegrees = { largeDegrees, smallDegrees };
-				foreach (double sideDegree in sideDegrees)
-				{
-					//3. Index random points in this cluster box
-					deleteAll();
-					var points = new List<Point>();
-					for (int i = 0; i < 20; i++)
-					{
-						double x = random.NextDouble() * sideDegree - sideDegree / 2 + clusterCenter.GetX();
-						double y = random.NextDouble() * sideDegree - sideDegree / 2 + clusterCenter.GetY();
-						Point pt = normPointXY(x, y);
-						points.Add(pt);
-						addDocument(newDoc("" + i, pt));
-					}
-					commit();
-
-					//3. Use 4 query centers. Each is radially out from each corner of cluster box by twice distance to box edge.
-					foreach (double qcXoff in new double[] { sideDegree, -sideDegree })
-					{//query-center X offset from cluster center
-						foreach (double qcYoff in new double[] { sideDegree, -sideDegree })
-						{//query-center Y offset from cluster center
-							Point queryCenter = normPointXY(qcXoff + clusterCenter.GetX(),
-								qcYoff + clusterCenter.GetY());
-							double[] distRange = calcDistRange(queryCenter, clusterCenter, sideDegree);
-							//4.1 query a small box getting nothing
-                            checkHits(q(queryCenter, distRange[0] * 0.99), 0, null);
-							//4.2 Query a large box enclosing the cluster, getting everything
-                            checkHits(q(queryCenter, distRange[1] * 1.01), points.Count, null);
-							//4.3 Query a medium box getting some (calculate the correct solution and verify)
-							double queryDist = distRange[0] + (distRange[1] - distRange[0]) / 2;//average
-
-							//Find matching points.  Put into int[] of doc ids which is the same thing as the index into points list.
-							int[] ids = new int[points.Count];
-							int ids_sz = 0;
-							for (int i = 0; i < points.Count; i++)
-							{
-								Point point = points[i];
-								if (ctx.GetDistCalc().Distance(queryCenter, point) <= queryDist)
-									ids[ids_sz++] = i;
-							}
-							
-							var ids_new = new int[ids_sz]; // will pad with 0's if larger
-							Array.Copy(ids, ids_new, ids_sz);
-							ids = ids_new;
-							//assert ids_sz > 0 (can't because randomness keeps us from being able to)
-
-                            checkHits(q(queryCenter, queryDist), ids.Length, ids);
-						}
-					}
-
-				}//for sideDegree
-
-			}//for clusterCenter
+        [Test]
+        public void geohashRecursiveRandom()
+        {
+            init(12);
+            var random = NewRandom();
 
-		}//randomTest()
+            //1. Iterate test with the cluster at some worldly point of interest
+            var clusterCenters = new Point[] {ctx.MakePoint(-180, 0), ctx.MakePoint(0, 90), ctx.MakePoint(0, -90)};
+            foreach (var clusterCenter in clusterCenters)
+            {
+                //2. Iterate on size of cluster (a really small one and a large one)
+                String hashCenter = GeohashUtils.EncodeLatLon(clusterCenter.GetY(), clusterCenter.GetX(), maxLength);
+                //calculate the number of degrees in the smallest grid box size (use for both lat & lon)
+                String smallBox = hashCenter.Substring(0, hashCenter.Length - 1); //chop off leaf precision
+                Rectangle clusterDims = GeohashUtils.DecodeBoundary(smallBox, ctx);
+                double smallRadius = Math.Max(clusterDims.GetMaxX() - clusterDims.GetMinX(),
+                                              clusterDims.GetMaxY() - clusterDims.GetMinY());
+                Assert.IsTrue(smallRadius < 1);
+                const double largeRadius = 20d; //good large size; don't use >=45 for this test code to work
+                double[] radiusDegs = {largeRadius, smallRadius};
+                foreach (double radiusDeg in radiusDegs)
+                {
+                    //3. Index random points in this cluster box
+                    deleteAll();
+                    var points = new List<Point>();
+                    for (int i = 0; i < 20; i++)
+                    {
+                        //Note that this will not result in randomly distributed points in the
+                        // circle, they will be concentrated towards the center a little. But
+                        // it's good enough.
+                        Point pt = ctx.GetDistCalc().PointOnBearing(clusterCenter,
+                                                                    random.NextDouble()*radiusDeg, random.Next()*360,
+                                                                    ctx, null);
+                        pt = alignGeohash(pt);
+                        points.Add(pt);
+                        addDocument(newDoc("" + i, pt));
+                    }
+                    commit();
+
+                    //3. Use some query centers. Each is twice the cluster's radius away.
+                    for (int ri = 0; ri < 4; ri++)
+                    {
+                        Point queryCenter = ctx.GetDistCalc().PointOnBearing(clusterCenter,
+                                                                             radiusDeg*2, random.Next(360), ctx, null);
+                        queryCenter = alignGeohash(queryCenter);
+                        //4.1 Query a small box getting nothing
+                        checkHits(q(queryCenter, radiusDeg - smallRadius/2), 0, null);
+                        //4.2 Query a large box enclosing the cluster, getting everything
+                        checkHits(q(queryCenter, radiusDeg*3 + smallRadius/2), points.Count, null);
+                        //4.3 Query a medium box getting some (calculate the correct solution and verify)
+                        double queryDist = radiusDeg*2;
+
+                        //Find matching points.  Put into int[] of doc ids which is the same thing as the index into points list.
+                        int[] ids = new int[points.Count];
+                        int ids_sz = 0;
+                        for (int i = 0; i < points.Count; i++)
+                        {
+                            Point point = points[i];
+                            if (ctx.GetDistCalc().Distance(queryCenter, point) <= queryDist)
+                                ids[ids_sz++] = i;
+                        }
+
+                        var ids_new = new int[ids_sz]; // will pad with 0's if larger
+                        Array.Copy(ids, ids_new, ids_sz);
+                        ids = ids_new;
+                        //assert ids_sz > 0 (can't because randomness keeps us from being able to)
+
+                        checkHits(q(queryCenter, queryDist), ids.Length, ids);
+                    }
+                } //for radiusDeg
+            } //for clusterCenter
+        }
 
         private SpatialArgs q(Point pt, double dist, double distErrPct = 0.0)
         {
@@ -181,66 +184,28 @@ namespace Lucene.Net.Contrib.Spatial.Tes
         }
 
         private void checkHits(SpatialArgs args, int assertNumFound, int[] assertIds)
-		{
-			SearchResults got = executeQuery(strategy.MakeQuery(args), 100);
+        {
+            SearchResults got = executeQuery(strategy.MakeQuery(args), 100);
             assertEquals("" + args, assertNumFound, got.numFound);
-			if (assertIds != null)
-			{
-				var gotIds = new HashSet<int>();
-				foreach (SearchResult result in got.results)
-				{
-					gotIds.Add(int.Parse(result.document.Get("id")));
-				}
-				foreach (int assertId in assertIds)
-				{
-					Assert.True(gotIds.Contains(assertId), "has " + assertId);
-				}
-			}
-		}
-
-		private Document newDoc(String id, Shape shape)
-		{
-			Document doc = new Document();
-			doc.Add(new Field("id", id, Field.Store.YES, Field.Index.ANALYZED));
-			foreach (var f in strategy.CreateIndexableFields(shape))
-			{
-				doc.Add(f);
-			}
-			if (storeShape)
-				doc.Add(new Field(strategy.GetFieldName(), ctx.ToString(shape), Field.Store.YES, Field.Index.ANALYZED));
-			return doc;
-		}
-
-		private double[] calcDistRange(Point startPoint, Point targetCenter, double targetSideDegrees)
-		{
-			double min = Double.MaxValue;
-			double max = Double.MinValue;
-			foreach (double xLen in new double[] { targetSideDegrees, -targetSideDegrees })
-			{
-				foreach (double yLen in new double[] { targetSideDegrees, -targetSideDegrees })
-				{
-					Point p2 = normPointXY(targetCenter.GetX() + xLen / 2, targetCenter.GetY() + yLen / 2);
-					double d = ctx.GetDistCalc().Distance(startPoint, p2);
-					min = Math.Min(min, d);
-					max = Math.Max(max, d);
-				}
-			}
-			return new double[] { min, max };
-		}
-
-		/** Normalize x & y (put in lon-lat ranges) & ensure geohash round-trip for given precision. */
-		private Point normPointXY(double x, double y)
-		{
-			//put x,y as degrees into double[] as radians
-			double[] latLon = { y * DistanceUtils.DEG_180_AS_RADS, DistanceUtils.ToRadians(x) };
-			DistanceUtils.NormLatRAD(latLon);
-			DistanceUtils.NormLatRAD(latLon);
-			double x2 = DistanceUtils.ToDegrees(latLon[1]);
-			double y2 = DistanceUtils.ToDegrees(latLon[0]);
-			//overwrite latLon, units is now degrees
+            if (assertIds != null)
+            {
+                var gotIds = new HashSet<int>();
+                foreach (SearchResult result in got.results)
+                {
+                    gotIds.Add(int.Parse(result.document.Get("id")));
+                }
+                foreach (int assertId in assertIds)
+                {
+                    Assert.True(gotIds.Contains(assertId), "has " + assertId);
+                }
+            }
+        }
 
-			return GeohashUtils.Decode(GeohashUtils.EncodeLatLon(y2, x2, maxLength), ctx);
-		}
+        /** NGeohash round-trip for given precision. */
 
-	}
+        private Point alignGeohash(Point p)
+        {
+            return GeohashUtils.Decode(GeohashUtils.EncodeLatLon(p.GetY(), p.GetX(), maxLength), ctx);
+        }
+    }
 }

Modified: lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs Sat Sep 22 23:04:38 2012
@@ -32,10 +32,10 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		[Test]
 		public void testNGramPrefixGridLosAngeles()
 		{
-			SpatialContext ctx = SpatialContext.GEO_KM;
+			SpatialContext ctx = SpatialContext.GEO;
 			TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx), "geo");
 
-			Shape point = new PointImpl(-118.243680, 34.052230);
+			Shape point = ctx.MakePoint(-118.243680, 34.052230);
 
 			Document losAngeles = new Document();
 			losAngeles.Add(new Field("name", "Los Angeles", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
@@ -51,7 +51,7 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 			SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
 			// TODO... use a non polygon query
 			//    SpatialArgs spatialArgs = spatialArgsParser.parse(
-			//        "IsWithin(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
+            //        "Intersects(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
 			//        new SimpleSpatialContext());
 
 			//    Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);

Modified: lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs Sat Sep 22 23:04:38 2012
@@ -33,7 +33,7 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		  public override void SetUp()
 		{
 			base.SetUp();
-			ctx = SpatialContext.GEO_KM;
+			ctx = SpatialContext.GEO;
 			trie = new GeohashPrefixTree(ctx, 4);
 		}
 

Modified: lucene.net/trunk/test/contrib/Spatial/Queries/SpatialArgsParserTest.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Queries/SpatialArgsParserTest.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Queries/SpatialArgsParserTest.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/Queries/SpatialArgsParserTest.cs Sat Sep 22 23:04:38 2012
@@ -8,7 +8,7 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 {
 	public class SpatialArgsParserTest
 	{
-		private readonly SpatialContext ctx = SpatialContext.GEO_KM;
+		private readonly SpatialContext ctx = SpatialContext.GEO;
 
 		//The args parser is only dependent on the ctx for IO so I don't care to test
 		// with other implementations.
@@ -21,7 +21,7 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 			String arg = SpatialOperation.IsWithin + "(-10 -20 10 20)";
 			SpatialArgs outValue = parser.Parse(arg, ctx);
 			Assert.AreEqual(SpatialOperation.IsWithin, outValue.Operation);
-			Rectangle bounds = (Rectangle)outValue.GetShape();
+			Rectangle bounds = (Rectangle)outValue.Shape;
 			Assert.AreEqual(-10.0, bounds.GetMinX(), 0D);
 			Assert.AreEqual(10.0, bounds.GetMaxX(), 0D);
 

Modified: lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs Sat Sep 22 23:04:38 2012
@@ -35,7 +35,7 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		private DirectoryReader indexReader;
 		private IndexWriter indexWriter;
 		private Directory directory;
-		private IndexSearcher indexSearcher;
+		protected IndexSearcher indexSearcher;
 
 		[SetUp]
 		public override void SetUp()

Modified: lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs Sat Sep 22 23:04:38 2012
@@ -19,158 +19,232 @@ using System;
 using System.Collections.Generic;
 using System.IO;
 using Lucene.Net.Documents;
+using Lucene.Net.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Search.Function;
 using Lucene.Net.Spatial;
 using Lucene.Net.Spatial.Queries;
+using Lucene.Net.Spatial.Util;
 using Lucene.Net.Util;
 using NUnit.Framework;
 using Spatial4n.Core.Context;
+using Spatial4n.Core.Io;
 using Spatial4n.Core.Io.Samples;
 using Spatial4n.Core.Shapes;
 
 namespace Lucene.Net.Contrib.Spatial.Test
 {
-	public abstract class StrategyTestCase : SpatialTestCase
-	{
-		public static readonly String DATA_SIMPLE_BBOX = "simple-bbox.txt";
-		public static readonly String DATA_STATES_POLY = "states-poly.txt";
-		public static readonly String DATA_STATES_BBOX = "states-bbox.txt";
-		public static readonly String DATA_COUNTRIES_POLY = "countries-poly.txt";
-		public static readonly String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
-		public static readonly String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";
+    public abstract class StrategyTestCase : SpatialTestCase
+    {
+        public static readonly String DATA_SIMPLE_BBOX = "simple-bbox.txt";
+        public static readonly String DATA_STATES_POLY = "states-poly.txt";
+        public static readonly String DATA_STATES_BBOX = "states-bbox.txt";
+        public static readonly String DATA_COUNTRIES_POLY = "countries-poly.txt";
+        public static readonly String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
+        public static readonly String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";
 
+        public static readonly String QTEST_States_IsWithin_BBox = "states-IsWithin-BBox.txt";
+        public static readonly String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
         public static readonly String QTEST_Cities_Intersects_BBox = "cities-Intersects-BBox.txt";
-		public static readonly String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
-		public static readonly String QTEST_Cities_IsWithin_BBox = "cities-IsWithin-BBox.txt";
-		public static readonly String QTEST_Simple_Queries_BBox = "simple-Queries-BBox.txt";
-
-		//private Logger log = Logger.getLogger(getClass().getName());
-
-		protected readonly SpatialArgsParser argsParser = new SpatialArgsParser();
-
-		protected SpatialStrategy strategy;
-		protected SpatialContext ctx;
-		protected bool storeShape = true;
-
-		protected void executeQueries(SpatialMatchConcern concern, params String[] testQueryFile)
-		{
-			Console.WriteLine("testing queried for strategy " + strategy);
-			foreach (String path in testQueryFile)
-			{
-				IEnumerator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
-				runTestQueries(testQueryIterator, concern);
-			}
-		}
-
-		protected void getAddAndVerifyIndexedDocuments(String testDataFile)
-		{
-			List<Document> testDocuments = getDocuments(testDataFile);
-			addDocumentsAndCommit(testDocuments);
-			verifyDocumentsIndexed(testDocuments.Count);
-		}
-
-		protected List<Document> getDocuments(String testDataFile)
-		{
-			IEnumerator<SampleData> sampleData = getSampleData(testDataFile);
-			var documents = new List<Document>();
-			while (sampleData.MoveNext())
-			{
-				SampleData data = sampleData.Current;
-				var document = new Document();
-				document.Add(new Field("id", data.id, Field.Store.YES, Field.Index.ANALYZED));
-				document.Add(new Field("name", data.name, Field.Store.YES, Field.Index.ANALYZED));
-				Shape shape = ctx.ReadShape(data.shape);
-				foreach (var f in strategy.CreateIndexableFields(shape))
-				{
-					document.Add(f);
-				}
-				if (storeShape)
-					document.Add(strategy.CreateStoredField(shape));
-
-				documents.Add(document);
-			}
-			return documents;
-		}
-
-		protected IEnumerator<SampleData> getSampleData(String testDataFile)
-		{
-            var stream = File.OpenRead(Path.Combine(Paths.ProjectRootDirectory, Path.Combine(@"test-files\spatial\data", testDataFile)));
-			return new SampleDataReader(stream);
-		}
-
-		protected IEnumerator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx)
-		{
-			var @in = File.OpenRead(Path.Combine(Paths.ProjectRootDirectory, Path.Combine(@"test-files\spatial", testQueryFile)));
-			return SpatialTestQuery.getTestQueries(argsParser, ctx, testQueryFile, @in);
-		}
-
-		public void runTestQueries(
-			IEnumerator<SpatialTestQuery> queries,
-			SpatialMatchConcern concern)
-		{
-			while (queries.MoveNext())
-			{
-				SpatialTestQuery q = queries.Current;
-
-				String msg = q.line; //"Query: " + q.args.toString(ctx);
-				SearchResults got = executeQuery(strategy.MakeQuery(q.args), 100);
-				if (storeShape && got.numFound > 0)
-				{
-					//check stored value is there & parses
-					Assert.NotNull(ctx.ReadShape(got.results[0].document.Get(strategy.GetFieldName())));
-				}
-				if (concern.orderIsImportant)
-				{
-					var ids = q.ids.GetEnumerator();
-					foreach (var r in got.results)
-					{
-						String id = r.document.Get("id");
-						if (!ids.MoveNext())
-							Assert.Fail(msg + " :: Did not get enough results.  Expected " + q.ids + ", got: " + got.toDebugString());
-						Assert.AreEqual(ids.Current, id, "out of order: " + msg);
-					}
-					if (ids.MoveNext())
-					{
-						Assert.Fail(msg + " :: expect more results then we got: " + ids.Current);
-					}
-				}
-				else
-				{
-					// We are looking at how the results overlap
-					if (concern.resultsAreSuperset)
-					{
-						var found = new HashSet<String>();
-						foreach (var r in got.results)
-						{
-							found.Add(r.document.Get("id"));
-						}
-						foreach (String s in q.ids)
-						{
-							if (!found.Contains(s))
-							{
-								Assert.Fail("Results are mising id: " + s + " :: " + found);
-							}
-						}
-					}
-					else
-					{
-						var found = new List<String>();
-						foreach (SearchResult r in got.results)
-						{
-							found.Add(r.document.Get("id"));
-						}
-
-						// sort both so that the order is not important
-						q.ids.Sort();
-						found.Sort();
-						Assert.AreEqual(q.ids.Count, found.Count);
-						for (var i = 0; i < found.Count; i++)
-						{
-							Assert.AreEqual(q.ids[i], found[i], msg);
-						}
-					}
-				}
-			}
-		}
+        public static readonly String QTEST_Simple_Queries_BBox = "simple-Queries-BBox.txt";
 
-	}
+        //private Logger log = Logger.getLogger(getClass().getName());
+
+        protected readonly SpatialArgsParser argsParser = new SpatialArgsParser();
+
+        protected SpatialStrategy strategy;
+        protected SpatialContext ctx;
+        protected bool storeShape = true;
+
+        protected void executeQueries(SpatialMatchConcern concern, params String[] testQueryFile)
+        {
+            Console.WriteLine("testing queries for strategy " + strategy);
+            foreach (String path in testQueryFile)
+            {
+                IEnumerator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
+                runTestQueries(testQueryIterator, concern);
+            }
+        }
+
+        protected void getAddAndVerifyIndexedDocuments(String testDataFile)
+        {
+            List<Document> testDocuments = getDocuments(testDataFile);
+            addDocumentsAndCommit(testDocuments);
+            verifyDocumentsIndexed(testDocuments.Count);
+        }
+
+        protected List<Document> getDocuments(String testDataFile)
+        {
+            IEnumerator<SampleData> sampleData = getSampleData(testDataFile);
+            var documents = new List<Document>();
+            while (sampleData.MoveNext())
+            {
+                SampleData data = sampleData.Current;
+                var document = new Document();
+                document.Add(new Field("id", data.id, Field.Store.YES, Field.Index.ANALYZED));
+                document.Add(new Field("name", data.name, Field.Store.YES, Field.Index.ANALYZED));
+                Shape shape = new ShapeReadWriter(ctx).ReadShape(data.shape);
+                shape = convertShapeFromGetDocuments(shape);
+                if (shape != null)
+                {
+                    foreach (var f in strategy.CreateIndexableFields(shape))
+                    {
+                        document.Add(f);
+                    }
+                    if (storeShape)
+                        document.Add(new Field(strategy.GetFieldName(), ctx.ToString(shape), Field.Store.YES,
+                                               Field.Index.NOT_ANALYZED_NO_NORMS));
+                }
+
+                documents.Add(document);
+            }
+            return documents;
+        }
+
+        /** Subclasses may override to transform or remove a shape for indexing */
+
+        protected virtual Shape convertShapeFromGetDocuments(Shape shape)
+        {
+            return shape;
+        }
+
+        protected IEnumerator<SampleData> getSampleData(String testDataFile)
+        {
+            var stream =
+                File.OpenRead(Path.Combine(Paths.ProjectRootDirectory,
+                                           Path.Combine(@"test-files\spatial\data", testDataFile)));
+            return new SampleDataReader(stream);
+        }
+
+        protected IEnumerator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx)
+        {
+            var @in =
+                File.OpenRead(Path.Combine(Paths.ProjectRootDirectory,
+                                           Path.Combine(@"test-files\spatial", testQueryFile)));
+            return SpatialTestQuery.getTestQueries(argsParser, ctx, testQueryFile, @in);
+        }
+
+        public void runTestQueries(
+            IEnumerator<SpatialTestQuery> queries,
+            SpatialMatchConcern concern)
+        {
+            while (queries.MoveNext())
+            {
+                SpatialTestQuery q = queries.Current;
+
+                String msg = q.line; //"Query: " + q.args.toString(ctx);
+                SearchResults got = executeQuery(strategy.MakeQuery(q.args), 100);
+                if (storeShape && got.numFound > 0)
+                {
+                    //check stored value is there & parses
+                    assertNotNull(
+                        new ShapeReadWriter(ctx).ReadShape(got.results[0].document.Get(strategy.GetFieldName())));
+                }
+                if (concern.orderIsImportant)
+                {
+                    var ids = q.ids.GetEnumerator();
+                    foreach (var r in got.results)
+                    {
+                        String id = r.document.Get("id");
+                        if (!ids.MoveNext())
+                            Assert.Fail(msg + " :: Did not get enough results.  Expected " + q.ids + ", got: " +
+                                        got.toDebugString());
+                        Assert.AreEqual(ids.Current, id, "out of order: " + msg);
+                    }
+                    if (ids.MoveNext())
+                    {
+                        Assert.Fail(msg + " :: expect more results then we got: " + ids.Current);
+                    }
+                }
+                else
+                {
+                    // We are looking at how the results overlap
+                    if (concern.resultsAreSuperset)
+                    {
+                        var found = new HashSet<String>();
+                        foreach (var r in got.results)
+                        {
+                            found.Add(r.document.Get("id"));
+                        }
+                        foreach (String s in q.ids)
+                        {
+                            if (!found.Contains(s))
+                            {
+                                Assert.Fail("Results are mising id: " + s + " :: " + found);
+                            }
+                        }
+                    }
+                    else
+                    {
+                        var found = new List<String>();
+                        foreach (SearchResult r in got.results)
+                        {
+                            found.Add(r.document.Get("id"));
+                        }
+
+                        // sort both so that the order is not important
+                        q.ids.Sort();
+                        found.Sort();
+                        Assert.AreEqual(q.ids.Count, found.Count);
+                        for (var i = 0; i < found.Count; i++)
+                        {
+                            Assert.AreEqual(q.ids[i], found[i], msg);
+                        }
+                    }
+                }
+            }
+        }
+
+        protected void adoc(String id, String shapeStr)
+        {
+            Shape shape = shapeStr == null ? null : new ShapeReadWriter(ctx).ReadShape(shapeStr);
+            addDocument(newDoc(id, shape));
+        }
+
+        protected void adoc(String id, Shape shape)
+        {
+            addDocument(newDoc(id, shape));
+        }
+
+        protected virtual Document newDoc(String id, Shape shape)
+        {
+            Document doc = new Document();
+            doc.Add(new Field("id", id, Field.Store.YES, Field.Index.ANALYZED));
+            if (shape != null)
+            {
+                foreach (var f in strategy.CreateIndexableFields(shape))
+                {
+                    doc.Add(f);
+                }
+                if (storeShape)
+                    doc.Add(new Field(strategy.GetFieldName(), ctx.ToString(shape), Field.Store.YES,
+                                      Field.Index.NOT_ANALYZED_NO_NORMS));
+            }
+            return doc;
+        }
+
+        /** scores[] are in docId order */
+
+        protected void checkValueSource(ValueSource vs, float[] scores, float delta)
+        {
+            FunctionQuery q = new FunctionQuery(vs);
+
+            //    //TODO is there any point to this check?
+            //    int expectedDocs[] = new int[scores.length];//fill with ascending 0....length-1
+            //    for (int i = 0; i < expectedDocs.length; i++) {
+            //      expectedDocs[i] = i;
+            //    }
+            //    CheckHits.checkHits(random(), q, "", indexSearcher, expectedDocs);
+
+            TopDocs docs = indexSearcher.Search(q, 1000); //calculates the score
+            for (int i = 0; i < docs.ScoreDocs.Length; i++)
+            {
+                ScoreDoc gotSD = docs.ScoreDocs[i];
+                float expectedScore = scores[gotSD.Doc];
+                assertEquals("Not equal for doc " + gotSD.Doc, expectedScore, gotSD.Score, delta);
+            }
+
+            CheckHits.checkExplanations(q, "", indexSearcher);
+        }
+    }
 }

Modified: lucene.net/trunk/test/contrib/Spatial/Vector/TestTwoDoublesStrategy.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/contrib/Spatial/Vector/TestTwoDoublesStrategy.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/contrib/Spatial/Vector/TestTwoDoublesStrategy.cs (original)
+++ lucene.net/trunk/test/contrib/Spatial/Vector/TestTwoDoublesStrategy.cs Sat Sep 22 23:04:38 2012
@@ -31,14 +31,14 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		public override void SetUp()
 		{
 			base.SetUp();
-			this.ctx = SpatialContext.GEO_KM;
+			this.ctx = SpatialContext.GEO;
 			this.strategy = new TwoDoublesStrategy(ctx, GetType().Name);
 		}
 
 		[Test]
 		public void testCircleShapeSupport()
 		{
-			Circle circle = new CircleImpl(new PointImpl(0, 0), 10, this.ctx);
+            Circle circle = ctx.MakeCircle(ctx.MakePoint(0, 0), 10);
 			SpatialArgs args = new SpatialArgs(SpatialOperation.Intersects, circle);
 			Query query = this.strategy.MakeQuery(args);
 
@@ -48,16 +48,16 @@ namespace Lucene.Net.Contrib.Spatial.Tes
 		[Test]
 		public void testInvalidQueryShape()
 		{
-			Point point = new PointImpl(0, 0);
+            Point point = ctx.MakePoint(0, 0);
 			var args = new SpatialArgs(SpatialOperation.Intersects, point);
 			Assert.Throws<InvalidShapeException>(() => this.strategy.MakeQuery(args));
 		}
 
 		[Test]
-		public void testCitiesWithinBBox()
+        public void testCitiesIntersectsBBox()
 		{
 			getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
-			executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox);
+			executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_Intersects_BBox);
 		}
 	}
 }

Modified: lucene.net/trunk/test/core/Util/LuceneTestCase.cs
URL: http://svn.apache.org/viewvc/lucene.net/trunk/test/core/Util/LuceneTestCase.cs?rev=1388918&r1=1388917&r2=1388918&view=diff
==============================================================================
--- lucene.net/trunk/test/core/Util/LuceneTestCase.cs (original)
+++ lucene.net/trunk/test/core/Util/LuceneTestCase.cs Sat Sep 22 23:04:38 2012
@@ -258,10 +258,40 @@ namespace Lucene.Net.Util
             Assert.AreEqual(d1, d2, delta);
         }
 
+        protected static void assertEquals(string msg, double d1, double d2, double delta)
+        {
+            Assert.AreEqual(d1, d2, delta, msg);
+        }
+
         protected static void assertTrue(bool cnd)
         {
             Assert.IsTrue(cnd);
         }
+
+        protected static void assertTrue(string msg, bool cnd)
+        {
+            Assert.IsTrue(cnd, msg);
+        }
+
+        protected static void assertNotNull(object o)
+        {
+            Assert.NotNull(o);
+        }
+
+        protected static void assertNotNull(string msg, object o)
+        {
+            Assert.NotNull(o, msg);
+        }
+
+        protected static void assertNull(object o)
+        {
+            Assert.Null(o);
+        }
+
+        protected static void assertNull(string msg, object o)
+        {
+            Assert.Null(o, msg);
+        }
         #endregion
     }
 }