Created
January 17, 2017 08:50
-
-
Save manofstick/2be555566581c5057b460e53e113cdcd to your computer and use it in GitHub Desktop.
A set of regression tests for lazy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
using System.Threading; | |
using System.Reflection; | |
namespace LazyTest | |
{ | |
[TestClass] | |
public class LazyRegressionTests | |
{ | |
class MyException | |
: Exception | |
{ | |
public int Value { get; } | |
public MyException(int value) | |
{ | |
Value = value; | |
} | |
} | |
public class Simple | |
{ | |
public int Value { get; } | |
public Simple(int value) | |
{ | |
Value = value; | |
} | |
public Simple() | |
{ | |
Value = 42; | |
} | |
} | |
public void SimpleInt(Lazy<int> lazy) | |
{ | |
Assert.IsFalse(lazy.IsValueCreated); | |
Assert.AreEqual(lazy.Value, 42); | |
Assert.IsTrue(lazy.IsValueCreated); | |
} | |
[TestMethod] | |
public void SimpleInteger() | |
{ | |
SimpleInt(new Lazy<int>(() => 42)); | |
SimpleInt(new Lazy<int>(() => 42, true)); | |
SimpleInt(new Lazy<int>(() => 42, false)); | |
SimpleInt(new Lazy<int>(() => 42, LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleInt(new Lazy<int>(() => 42, LazyThreadSafetyMode.None)); | |
SimpleInt(new Lazy<int>(() => 42, LazyThreadSafetyMode.PublicationOnly)); | |
} | |
public void SimpleObject(Lazy<Simple> lazy) | |
{ | |
Assert.IsFalse(lazy.IsValueCreated); | |
Assert.AreEqual(lazy.Value.Value, 42); | |
Assert.IsTrue(lazy.IsValueCreated); | |
} | |
[TestMethod] | |
public void SimpleObject() | |
{ | |
SimpleObject(new Lazy<Simple>()); | |
SimpleObject(new Lazy<Simple>(true)); | |
SimpleObject(new Lazy<Simple>(false)); | |
SimpleObject(new Lazy<Simple>(LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleObject(new Lazy<Simple>(LazyThreadSafetyMode.None)); | |
SimpleObject(new Lazy<Simple>(LazyThreadSafetyMode.PublicationOnly)); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42))); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42), true)); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42), false)); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42), LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42), LazyThreadSafetyMode.None)); | |
SimpleObject(new Lazy<Simple>(() => new Simple(42), LazyThreadSafetyMode.PublicationOnly)); | |
} | |
public void SimpleIntException(Lazy<int> lazy) | |
{ | |
MyException e = null; | |
try | |
{ | |
var _ = lazy.Value; | |
} | |
catch(MyException thrown) | |
{ | |
e = thrown; | |
} | |
Assert.IsNotNull(e); | |
Assert.AreEqual(e.Value, 99); | |
} | |
[TestMethod] | |
[ExpectedException(typeof(MyException), "")] | |
public void SimpleIntegerException() | |
{ | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); })); | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); }, true)); | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); }, false)); | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.None)); | |
SimpleInt(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.PublicationOnly)); | |
} | |
public class SimpleException | |
{ | |
public SimpleException() : this(99) { } | |
public SimpleException(int value) | |
{ | |
throw new MyException(value); | |
} | |
} | |
public void SimpleObjectException(Lazy<SimpleException> lazy) | |
{ | |
TargetInvocationException e = null; | |
try | |
{ | |
var _ = lazy.Value; | |
} | |
catch (TargetInvocationException ex) | |
{ | |
e = ex; | |
} | |
Assert.IsNotNull(e); | |
} | |
[TestMethod] | |
[ExpectedException(typeof(MyException), "")] | |
public void SimpleObjectException() | |
{ | |
SimpleObjectException(new Lazy<SimpleException>()); | |
SimpleObjectException(new Lazy<SimpleException>(true)); | |
SimpleObjectException(new Lazy<SimpleException>(false)); | |
SimpleObjectException(new Lazy<SimpleException>(LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleObjectException(new Lazy<SimpleException>(LazyThreadSafetyMode.None)); | |
SimpleObjectException(new Lazy<SimpleException>(LazyThreadSafetyMode.PublicationOnly)); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99))); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99), true)); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99), false)); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.ExecutionAndPublication)); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.None)); | |
SimpleObjectException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.PublicationOnly)); | |
} | |
public void SameException<T>(Lazy<T> x) | |
{ | |
Exception first = null; | |
try | |
{ | |
var _ = x.Value; | |
} | |
catch (Exception thrown1) | |
{ | |
first = thrown1; | |
} | |
Assert.IsNotNull(first); | |
try | |
{ | |
var _ = x.Value; | |
} | |
catch (MyException thrown2) | |
{ | |
Assert.AreSame(first, thrown2); | |
} | |
} | |
public void DifferentException<T>(Lazy<T> x) | |
{ | |
Exception first = null; | |
try | |
{ | |
var _ = x.Value; | |
} | |
catch (Exception thrown1) | |
{ | |
first = thrown1; | |
} | |
Assert.IsNotNull(first); | |
Exception second = null; | |
try | |
{ | |
var _ = x.Value; | |
} | |
catch (Exception thrown2) | |
{ | |
second = thrown2; | |
} | |
Assert.IsNotNull(second); | |
Assert.AreNotEqual(first, second); | |
} | |
[TestMethod] | |
public void SameException() | |
{ | |
SameException(new Lazy<int>(() => { throw new MyException(99); })); | |
SameException(new Lazy<int>(() => { throw new MyException(99); }, true)); | |
SameException(new Lazy<int>(() => { throw new MyException(99); }, false)); | |
SameException(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.ExecutionAndPublication)); | |
SameException(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.None)); | |
DifferentException(new Lazy<int>(() => { throw new MyException(99); }, LazyThreadSafetyMode.PublicationOnly)); | |
DifferentException(new Lazy<SimpleException>()); | |
DifferentException(new Lazy<SimpleException>(true)); | |
DifferentException(new Lazy<SimpleException>(false)); | |
DifferentException(new Lazy<SimpleException>(LazyThreadSafetyMode.ExecutionAndPublication)); | |
DifferentException(new Lazy<SimpleException>(LazyThreadSafetyMode.None)); | |
DifferentException(new Lazy<SimpleException>(LazyThreadSafetyMode.PublicationOnly)); | |
SameException(new Lazy<SimpleException>(() => new SimpleException(99))); | |
SameException(new Lazy<SimpleException>(() => new SimpleException(99), true)); | |
SameException(new Lazy<SimpleException>(() => new SimpleException(99), false)); | |
SameException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.ExecutionAndPublication)); | |
SameException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.None)); | |
DifferentException(new Lazy<SimpleException>(() => new SimpleException(99), LazyThreadSafetyMode.PublicationOnly)); | |
} | |
public void MultipleInt(Lazy<int> lazy, ref int counter, int expected) | |
{ | |
counter = 0; | |
var result = 0; | |
for (var i=0; i < 10; ++i) | |
{ | |
try { result = lazy.Value; } catch (Exception) { } | |
} | |
Assert.AreEqual(result, expected); | |
} | |
[TestMethod] | |
public void Multiple() | |
{ | |
var counter = 0; | |
var f = new Func<int>(() => { if (++counter < 5) throw new MyException(42); else return counter; }); | |
MultipleInt(new Lazy<int>(f), ref counter, 0); | |
MultipleInt(new Lazy<int>(f, true), ref counter, 0); | |
MultipleInt(new Lazy<int>(f, false), ref counter, 0); | |
MultipleInt(new Lazy<int>(f, LazyThreadSafetyMode.ExecutionAndPublication), ref counter, 0); | |
MultipleInt(new Lazy<int>(f, LazyThreadSafetyMode.None), ref counter, 0); | |
MultipleInt(new Lazy<int>(f, LazyThreadSafetyMode.PublicationOnly), ref counter, 5); | |
} | |
public void MultipleObject(Lazy<Simple> lazy, ref int counter, int? expected) | |
{ | |
counter = 0; | |
var result = default(Simple); | |
for (var i = 0; i < 10; ++i) | |
{ | |
try { result = lazy.Value; } catch (Exception) { } | |
} | |
if (expected == null) | |
Assert.IsNull(result); | |
else | |
Assert.AreEqual(result.Value, expected.Value); | |
} | |
[TestMethod] | |
public void MultipleObject() | |
{ | |
var counter = 0; | |
var f = new Func<Simple>(() => { if (++counter < 5) throw new MyException(42); else return new Simple(counter); }); | |
MultipleObject(new Lazy<Simple>(f), ref counter, null); | |
MultipleObject(new Lazy<Simple>(f, true), ref counter, null); | |
MultipleObject(new Lazy<Simple>(f, false), ref counter, null); | |
MultipleObject(new Lazy<Simple>(f, LazyThreadSafetyMode.ExecutionAndPublication), ref counter, null); | |
MultipleObject(new Lazy<Simple>(f, LazyThreadSafetyMode.None), ref counter, null); | |
MultipleObject(new Lazy<Simple>(f, LazyThreadSafetyMode.PublicationOnly), ref counter, 5); | |
} | |
class SimpleConstructor | |
{ | |
public static int counter = 0; | |
public static int getValue() | |
{ | |
if (++counter < 5) | |
throw new MyException(42); | |
else | |
return counter; | |
} | |
public int Value { get; } | |
public SimpleConstructor() | |
{ | |
Value = getValue(); | |
} | |
} | |
void MultipleObject(Lazy<SimpleConstructor> lazy, int? expected) | |
{ | |
SimpleConstructor.counter = 0; | |
var result = default(SimpleConstructor); | |
for (var i = 0; i < 10; ++i) | |
{ | |
try { result = lazy.Value; } catch (Exception) { } | |
} | |
if (expected == null) | |
Assert.IsNull(result); | |
else | |
Assert.AreEqual(result.Value, expected.Value); | |
} | |
[TestMethod] | |
public void MultipleConstructorObject() | |
{ | |
MultipleObject(new Lazy<SimpleConstructor>(), 5); | |
MultipleObject(new Lazy<SimpleConstructor>(true), 5); | |
MultipleObject(new Lazy<SimpleConstructor>(false), 5); | |
MultipleObject(new Lazy<SimpleConstructor>(LazyThreadSafetyMode.ExecutionAndPublication), 5); | |
MultipleObject(new Lazy<SimpleConstructor>(LazyThreadSafetyMode.None), 5); | |
MultipleObject(new Lazy<SimpleConstructor>(LazyThreadSafetyMode.PublicationOnly), 5); | |
} | |
public void CheckForInvalidOperationException<T>(ref Lazy<T> x, Lazy<T> lazy) | |
{ | |
x = lazy; | |
var correct = false; | |
try | |
{ | |
var _ = lazy.Value; | |
} | |
catch (InvalidOperationException) | |
{ | |
correct = true; | |
} | |
Assert.IsTrue(correct); | |
} | |
[TestMethod] | |
public void Recursion() | |
{ | |
Lazy<int> x = null; | |
Func<int> f = () => x.Value; | |
CheckForInvalidOperationException(ref x, new Lazy<int>(f)); | |
CheckForInvalidOperationException(ref x, new Lazy<int>(f, true)); | |
CheckForInvalidOperationException(ref x, new Lazy<int>(f, false)); | |
CheckForInvalidOperationException(ref x, new Lazy<int>(f, LazyThreadSafetyMode.ExecutionAndPublication)); | |
CheckForInvalidOperationException(ref x, new Lazy<int>(f, LazyThreadSafetyMode.None)); | |
// this just hangs in current implementation | |
// CheckForInvalidOperationException(ref x, new Lazy<int>(f, LazyThreadSafetyMode.PublicationOnly)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment