There is an error in the OverlapWith method of struct Interval.
The two cases other inside this and this inside other (see the trailing comment lines)
have been switched. The following version of Interval-test.cs reveals the error: In the systematic tests shown above the test methods OverlapTest_This_ContainedIn_Other
and OverlapTest_Other_ContainedIn_This both fail. The above version of Interval-test.cs also shows the test of the indexer. Here is the correct version of the method OverlapWith: With this version of OverlapWith all test are executed successfully.using System;
using NUnit.Framework;
[TestFixture]
public class IntervalTestExtra{
Interval iv_1, iv_2, iv_3, iv_4;
[SetUp]
public void Init(){
iv_1 = new Interval(3,8);
iv_2 = new Interval(8,3);
iv_3 = new Interval(3,3);
iv_4 = Interval.MakeEmptyInterval();
}
// All tests proposed initially should be here.
[Test]
public void IndexerTest1(){
Assert.AreEqual(iv_1[0], 3, "Indexer of iv_1 - at index 0");
}
[Test]
public void IndexerTest2(){
Assert.AreEqual(iv_1[iv_1.Length-1], 8, "Indexer of iv_1 - at index Length-1");
}
[Test]
public void IndexerTest3(){
Assert.AreEqual(iv_2[0], 8, "Indexer of iv_2 - at index 0");
}
[Test]
public void IndexerTest4(){
Assert.AreEqual(iv_2[iv_2.Length-1], 3, "Indexer of iv_2 - at index Length-1");
}
[Test]
public void IndexerTest5(){
Assert.AreEqual(iv_3[0], 3, "Indexer of iv_3 - at index 0");
}
[Test]
public void IndexerTest6(){
Assert.AreEqual(iv_3[iv_3.Length-1], 3, "Indexer of iv_3 - at index Length-1");
}
[Test, ExpectedException("System.IndexOutOfRangeException")]
public void IndexerTestEmpty(){
int res = iv_4[0];
}
[Test, ExpectedException("System.IndexOutOfRangeException")]
public void IndexerRangeProblem_1(){
int res = iv_1[6];
}
[Test, ExpectedException("System.IndexOutOfRangeException")]
public void IndexerRangeProblem_2(){
int res = iv_1[-1];
}
// I have NOT included tests of <<, >>, *, -, !, and the conversion to an array.
// Do it yourself!
[Test]
public void OverlapTest1(){
Interval iv_1 = new Interval(3,8),
iv_2 = new Interval(3,8);
Assert.AreEqual(iv_1.OverlapWith(iv_2).From, 3, "part 1", "Overlap: Indentical");
Assert.AreEqual(iv_1.OverlapWith(iv_2).To, 8, "part 2", "Overlap: Indentical");
}
[Test]
public void OverlapTestIdentical(){
Interval iv_1 = Interval.MakeEmptyInterval(),
iv_2 = Interval.MakeEmptyInterval();
Assert.IsTrue(iv_1.OverlapWith(iv_2).Empty);
}
[Test]
public void OverlapTest_Empty_NonEmpty(){
Interval iv_1 = Interval.MakeEmptyInterval(),
iv_2 = new Interval(3,8);
Assert.IsTrue(iv_1.OverlapWith(iv_2).Empty);
}
[Test]
public void OverlapTest_NonEmpty_Empty(){
Interval iv_1 = new Interval(3,8),
iv_2 = Interval.MakeEmptyInterval();
Assert.IsTrue(iv_1.OverlapWith(iv_2).Empty);
}
[Test]
public void OverlapTest_Disjoint_Left(){
Interval iv_1 = new Interval(3,8),
iv_2 = new Interval(9,13);
Assert.IsTrue(iv_1.OverlapWith(iv_2).Empty);
}
[Test]
public void OverlapTest_Disjoint_Right(){
Interval iv_1 = new Interval(3,8),
iv_2 = new Interval(-3,0);
Assert.IsTrue(iv_1.OverlapWith(iv_2).Empty);
}
[Test]
public void OverlapTest_Other_ContainedIn_This(){
Interval iv_1 = new Interval(3,8),
iv_2 = new Interval(4,7);
Assert.AreEqual(iv_1.OverlapWith(iv_2).From, 4, "To");
Assert.AreEqual(iv_1.OverlapWith(iv_2).To, 7, "From" );
}
[Test]
public void OverlapTest_This_ContainedIn_Other(){
Interval iv_1 = new Interval(4,7),
iv_2 = new Interval(3,8);
Assert.AreEqual(iv_1.OverlapWith(iv_2).From, 4, "To");
Assert.AreEqual(iv_1.OverlapWith(iv_2).To, 7, "From");
}
[Test]
public void OverlapTest_OverlapsAtLeft(){
Interval iv_1 = new Interval(4,7),
iv_2 = new Interval(2,5);
Assert.AreEqual(iv_1.OverlapWith(iv_2).From, 4);
Assert.AreEqual(iv_1.OverlapWith(iv_2).To, 5);
}
[Test]
public void OverlapTest_OverlapsAtRight(){
Interval iv_1 = new Interval(4,7),
iv_2 = new Interval(6,10);
Assert.AreEqual(iv_1.OverlapWith(iv_2).From, 6);
Assert.AreEqual(iv_1.OverlapWith(iv_2).To, 7);
}
}
public Interval OverlapWith (Interval other){
// Positively oriented intervals:
Interval thisPI = (this.Orientation < 0) ? !this : this,
otherPI = (other.Orientation < 0) ? !other : other,
res;
if (thisPI.Empty || otherPI.Empty) // both empty
res = MakeEmptyInterval();
else if (thisPI.From > otherPI.To || thisPI.To < otherPI.From) // disjoint
res = MakeEmptyInterval();
else if (thisPI.From < otherPI.From && otherPI.To < thisPI.To) // other inside this
res = otherPI;
else if (otherPI.From <= thisPI.From && thisPI.To <= otherPI.To) // this inside other
res = thisPI;
else if (thisPI.From <= otherPI.From && otherPI.From <= thisPI.To) // this overlaps left border of other
res = new Interval(otherPI.From, thisPI.To);
else if (otherPI.From <= thisPI.From && thisPI.From <= otherPI.To) // other overlaps left border of this
res = new Interval(thisPI.From, otherPI.To);
else throw new Exception("Should not happen");
return (this.Orientation < 0) ? !res : res;
}