2129 lines
41 KiB
C#
2129 lines
41 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Linq;
|
||
|
using System.Reflection;
|
||
|
|
||
|
// Dynamic binary operator, unary operators and convert tests
|
||
|
|
||
|
public struct InverseLogicalOperator
|
||
|
{
|
||
|
bool value;
|
||
|
public InverseLogicalOperator (bool value)
|
||
|
{
|
||
|
this.value = value;
|
||
|
}
|
||
|
|
||
|
public static bool operator true (InverseLogicalOperator u)
|
||
|
{
|
||
|
return u.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator false (InverseLogicalOperator u)
|
||
|
{
|
||
|
return u.value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public struct MyType
|
||
|
{
|
||
|
int value;
|
||
|
|
||
|
public MyType (int value) : this ()
|
||
|
{
|
||
|
this.value = value;
|
||
|
}
|
||
|
|
||
|
public short ShortProp { get; set; }
|
||
|
|
||
|
public override int GetHashCode ()
|
||
|
{
|
||
|
throw new NotImplementedException ();
|
||
|
}
|
||
|
|
||
|
public static bool operator true (MyType a)
|
||
|
{
|
||
|
return a.value != 1;
|
||
|
}
|
||
|
|
||
|
public static bool operator false (MyType a)
|
||
|
{
|
||
|
return a.value == 0;
|
||
|
}
|
||
|
|
||
|
public static MyType operator + (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value + b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator - (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value - b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator / (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value / b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator * (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value * b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator % (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value % b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator &(MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value & b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator | (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value | b.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator ^ (MyType a, MyType b)
|
||
|
{
|
||
|
return new MyType (a.value ^ b.value);
|
||
|
}
|
||
|
|
||
|
public static bool operator == (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value == b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator != (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value != b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator > (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value > b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator < (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value < b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator >= (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value >= b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator <= (MyType a, MyType b)
|
||
|
{
|
||
|
return a.value <= b.value;
|
||
|
}
|
||
|
|
||
|
public static bool operator ! (MyType a)
|
||
|
{
|
||
|
return a.value > 0;
|
||
|
}
|
||
|
|
||
|
public static int operator ~ (MyType a)
|
||
|
{
|
||
|
return ~a.value;
|
||
|
}
|
||
|
|
||
|
public static MyType operator ++ (MyType a)
|
||
|
{
|
||
|
return new MyType (a.value * 2);
|
||
|
}
|
||
|
|
||
|
public static MyType operator -- (MyType a)
|
||
|
{
|
||
|
return new MyType (a.value / 2);
|
||
|
}
|
||
|
|
||
|
public static int operator >> (MyType a, int b)
|
||
|
{
|
||
|
return a.value >> b;
|
||
|
}
|
||
|
|
||
|
public static int operator << (MyType a, int b)
|
||
|
{
|
||
|
return a.value << b;
|
||
|
}
|
||
|
|
||
|
public static MyType operator - (MyType a)
|
||
|
{
|
||
|
return new MyType (-a.value);
|
||
|
}
|
||
|
|
||
|
public static MyType operator + (MyType a)
|
||
|
{
|
||
|
return new MyType (334455); // magic number
|
||
|
}
|
||
|
|
||
|
public override string ToString ()
|
||
|
{
|
||
|
return value.ToString ();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
class MyTypeExplicit
|
||
|
{
|
||
|
int value;
|
||
|
|
||
|
public MyTypeExplicit (int value)
|
||
|
{
|
||
|
this.value = value;
|
||
|
}
|
||
|
|
||
|
public static explicit operator int (MyTypeExplicit m)
|
||
|
{
|
||
|
return m.value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct MyTypeImplicitOnly
|
||
|
{
|
||
|
short b;
|
||
|
|
||
|
public MyTypeImplicitOnly (short b)
|
||
|
{
|
||
|
this.b = b;
|
||
|
}
|
||
|
|
||
|
public static implicit operator short (MyTypeImplicitOnly m)
|
||
|
{
|
||
|
return m.b;
|
||
|
}
|
||
|
|
||
|
public static implicit operator bool (MyTypeImplicitOnly m)
|
||
|
{
|
||
|
return m.b != 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enum MyEnum : byte
|
||
|
{
|
||
|
Value_1 = 1,
|
||
|
Value_2 = 2
|
||
|
}
|
||
|
|
||
|
enum MyEnumUlong : ulong
|
||
|
{
|
||
|
Value_1 = 1,
|
||
|
Value_2 = 2
|
||
|
}
|
||
|
|
||
|
|
||
|
class Tester
|
||
|
{
|
||
|
delegate void EmptyDelegate ();
|
||
|
event Action ev_assign;
|
||
|
|
||
|
static void Assert<T> (T expected, T value, string name)
|
||
|
{
|
||
|
if (!EqualityComparer<T>.Default.Equals (expected, value)) {
|
||
|
name += ": ";
|
||
|
throw new ApplicationException (name + expected + " != " + value);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void AssertChecked<T> (Func<T> expected, T value, string name)
|
||
|
{
|
||
|
try {
|
||
|
Assert (expected (), value, name);
|
||
|
throw new ApplicationException (name + ": OverflowException expected");
|
||
|
} catch (OverflowException) {
|
||
|
// passed
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void AssertChecked (Action expected, string name)
|
||
|
{
|
||
|
try {
|
||
|
expected ();
|
||
|
throw new ApplicationException (name + ": OverflowException expected");
|
||
|
} catch (OverflowException) {
|
||
|
// passed
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#pragma warning disable 169
|
||
|
|
||
|
void AddTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d + v, 7, "#1");
|
||
|
double v2 = 0.5;
|
||
|
Assert (d + v2, 5.5, "#1a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d + v3, new MyType (35), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (6);
|
||
|
Assert (d3 + new MyTypeImplicitOnly (11), 17, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d + v4, 9m, "#4");
|
||
|
}
|
||
|
|
||
|
void AddNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d + v2, null, "#1");
|
||
|
Assert<int?> (d + null, null, "#1a");
|
||
|
Assert<int?> (null + d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d + v2, 3, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 + 1, -1, "#2a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d + v3, new MyType (35), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 + new MyType (6), new MyType (-1), "#3a");
|
||
|
Assert<MyType?> (d3 + null, null, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d + v4, 9m, "#4");
|
||
|
v4 = null;
|
||
|
Assert<decimal?> (d + v4, null, "#4a");
|
||
|
}
|
||
|
|
||
|
void AddEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d + 1, MyEnum.Value_2, "#1");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert (d2 + (byte) 1, MyEnumUlong.Value_2, "#2");
|
||
|
Assert<MyEnumUlong?> (d2 + null, null, "#2a");
|
||
|
|
||
|
// CSC: Invalid System.InvalidOperationException
|
||
|
Assert<MyEnum?> (d + null, null, "#1");
|
||
|
}
|
||
|
|
||
|
void AddCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MaxValue;
|
||
|
AssertChecked (() => d + v, 7, "#1");
|
||
|
|
||
|
int? v2 = v;
|
||
|
AssertChecked (() => d + v2, null, "#2");
|
||
|
|
||
|
d = new MyType (3);
|
||
|
MyType v3 = new MyType (int.MaxValue);
|
||
|
Assert (new MyType (-2147483646), d + v3, "#3");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AddStringTest ()
|
||
|
{
|
||
|
dynamic d = "foo";
|
||
|
string v = "->";
|
||
|
Assert (d + v, "foo->", "#1");
|
||
|
Assert (d + 1, "foo1", "#1a");
|
||
|
Assert (d + null, "foo", "#1b");
|
||
|
Assert (d + 1 + v, "foo1->", "#1a");
|
||
|
|
||
|
uint? v2 = 4;
|
||
|
Assert (d + v2, "foo4", "#2");
|
||
|
}
|
||
|
|
||
|
void AddAssignTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
d += v;
|
||
|
Assert (d, 7, "#1");
|
||
|
|
||
|
d = 5.0;
|
||
|
double v2 = 0.5;
|
||
|
d += v2;
|
||
|
Assert (d, 5.5, "#1a");
|
||
|
d += v;
|
||
|
Assert (d, 7.5, "#1b");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 += new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-1), "#3");
|
||
|
|
||
|
d = 5m;
|
||
|
decimal v4 = 4m;
|
||
|
d += v4;
|
||
|
Assert (d, 9m, "#4");
|
||
|
}
|
||
|
|
||
|
void AddAssignNullableTest ()
|
||
|
{
|
||
|
dynamic d = (int?) 5;
|
||
|
|
||
|
// FEATURE
|
||
|
// For now it's impossible to use nullable compound assignment
|
||
|
// due to the way how DLR works. GetType () on nullable object returns
|
||
|
// underlying type and not nullable type, that means that
|
||
|
// C# binder is initialized with wrong operand type and any operation
|
||
|
// fails to resolve
|
||
|
/*
|
||
|
long? v2 = null;
|
||
|
d += v2;
|
||
|
Assert<int?> (d, null, "#1");
|
||
|
d += null;
|
||
|
Assert<int?> (d, null, "#1a");
|
||
|
|
||
|
long? l = (long?) 3;
|
||
|
d = l;
|
||
|
v2 = -2;
|
||
|
d += v2;
|
||
|
Assert (d, 3, "#2");
|
||
|
d = (int?) -2;
|
||
|
d += 1;
|
||
|
Assert (d, -1, "#2a");
|
||
|
|
||
|
MyType? v3 = new MyType (30);
|
||
|
d += v3;
|
||
|
Assert (d, new MyType (35), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 + new MyType (6), new MyType (-1), "#3a");
|
||
|
Assert<MyType?> (d3 + null, null, "#3b");
|
||
|
|
||
|
decimal? v4 = 4m;
|
||
|
d = 2m;
|
||
|
d += v4;
|
||
|
Assert (d, 9m, "#4");
|
||
|
d += null;
|
||
|
Assert<decimal?> (d, null, "#4a");
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
void AddAssignEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
d = MyEnum.Value_1;
|
||
|
d += 1;
|
||
|
Assert (d, MyEnum.Value_2, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
d2 += (byte) 1;
|
||
|
Assert (d2, MyEnumUlong.Value_2, "#3");
|
||
|
}
|
||
|
|
||
|
void AddAssignCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MaxValue;
|
||
|
AssertChecked (() => { d += v; Assert (d, 0, "#1-"); }, "#1");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (int.MaxValue);
|
||
|
d += v3;
|
||
|
Assert (d, new MyType (-2147483644), "#3-");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void AddAssignStringTest ()
|
||
|
{
|
||
|
dynamic d = "foo";
|
||
|
string v = "->";
|
||
|
d += v;
|
||
|
Assert (d, "foo->", "#1");
|
||
|
|
||
|
d = "foo";
|
||
|
d += 1;
|
||
|
Assert (d, "foo1", "#1a");
|
||
|
|
||
|
d += null;
|
||
|
Assert (d, "foo1", "#1b");
|
||
|
|
||
|
uint? v2 = 4;
|
||
|
d = "foo";
|
||
|
d += v2;
|
||
|
Assert (d, "foo4", "#2");
|
||
|
}
|
||
|
|
||
|
void AddAssignEvent ()
|
||
|
{
|
||
|
dynamic d = null;
|
||
|
|
||
|
// FIXME: Will have to special case events
|
||
|
// ev_assign += d;
|
||
|
}
|
||
|
|
||
|
void AndTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
Assert (d & v, false, "#1");
|
||
|
Assert (d & true, true, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
Assert (d & v2, 42, "#2");
|
||
|
Assert (d & 0, 0, "#2a");
|
||
|
|
||
|
d = new MyType (10);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d & v3, new MyType (10), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 & new MyType (6), new MyType (0), "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (6);
|
||
|
Assert (d3 & 11, 2, "#3b");
|
||
|
}
|
||
|
|
||
|
void AndTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert<MyEnum?> (d & null, null, "#1");
|
||
|
|
||
|
Assert (d & d, MyEnum.Value_1, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
|
||
|
}
|
||
|
|
||
|
void AndTestNullable ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d & v2, null, "#1");
|
||
|
Assert<int?> (d & null, null, "#1a");
|
||
|
Assert<int?> (null & d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d & v2, 4, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 & 1, 0, "#2a");
|
||
|
|
||
|
d = new MyType (22);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d & v3, new MyType (22), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 & new MyType (6), new MyType (0), "#3a");
|
||
|
Assert<MyType?> (d3 + null, null, "#3b");
|
||
|
|
||
|
dynamic a = (bool?) true;
|
||
|
dynamic b = (bool?) null;
|
||
|
Assert (a & b, (bool?)null, "#4a");
|
||
|
Assert (b & a, (bool?)null, "#4b");
|
||
|
}
|
||
|
|
||
|
void AndAssignedTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
d &= v;
|
||
|
Assert (d, false, "#1");
|
||
|
d = true;
|
||
|
d &= true;
|
||
|
Assert (d, true, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
d &= v2;
|
||
|
Assert (d, 42, "#2");
|
||
|
|
||
|
MyType v3 = new MyType (30);
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 &= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (0), "#3");
|
||
|
}
|
||
|
|
||
|
void AndAssignedTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
d &= MyEnum.Value_2;
|
||
|
Assert<MyEnum>(d, 0, "#1");
|
||
|
|
||
|
d = MyEnum.Value_2;
|
||
|
d &= d;
|
||
|
Assert (d, MyEnum.Value_2, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert<MyEnumUlong> (d2 & MyEnumUlong.Value_2, 0, "#3");
|
||
|
}
|
||
|
|
||
|
void AndAlsoTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
Assert<bool> (d && v, false, "#1");
|
||
|
|
||
|
Assert (d && true, true, "#1a");
|
||
|
|
||
|
d = true;
|
||
|
Assert (d && d, true, "#2");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 && new MyType (6), new MyType (0), "#3");
|
||
|
}
|
||
|
|
||
|
void DivideTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d / v, 2, "#1");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d / v3, new MyType (0), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 + new MyType (6), new MyType (-1), "#3a");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (6);
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d / v4, 1.5m, "#4");
|
||
|
}
|
||
|
|
||
|
void DivideNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
double? v2 = null;
|
||
|
Assert<double?> (d / v2, null, "#1");
|
||
|
Assert<double?> (d / null, null, "#1a");
|
||
|
Assert<double?> (null / d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d / v2, -2.5, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 / 1, -2, "#2a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d / v3, new MyType (0), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 / new MyType (6), new MyType (-1), "#3a");
|
||
|
Assert<MyType?> (d3 + null, null, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d / v4, 1.25m, "#4");
|
||
|
v4 = null;
|
||
|
Assert<decimal?> (d / v4, null, "#4a");
|
||
|
}
|
||
|
|
||
|
void DivideCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
// TODO:
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void DivideAssignTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
d /= v;
|
||
|
Assert (d, 2, "#1");
|
||
|
|
||
|
d = 5.0;
|
||
|
double v2 = 0.5;
|
||
|
d /= v2;
|
||
|
Assert (d, 10, "#1a");
|
||
|
d /= v;
|
||
|
Assert (d, 5, "#1b");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 /= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-1), "#3");
|
||
|
|
||
|
d = 5m;
|
||
|
decimal v4 = 4m;
|
||
|
d /= v4;
|
||
|
Assert (d, 1.25m, "#4");
|
||
|
}
|
||
|
|
||
|
void DivideAssignCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
// TODO:
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertImplicitTest ()
|
||
|
{
|
||
|
dynamic d = 3;
|
||
|
decimal v1 = d;
|
||
|
Assert (3m, v1, "#1");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
int v2 = d;
|
||
|
Assert (5, v2, "#2");
|
||
|
|
||
|
d = (byte) 4;
|
||
|
int v3 = d;
|
||
|
Assert (4, v3, "#3");
|
||
|
|
||
|
int[] v4 = new int[] { d };
|
||
|
Assert (4, v4[0], "#4");
|
||
|
|
||
|
d = true;
|
||
|
var v5 = new [] { d, 1 };
|
||
|
Assert (true, v5[0], "#5");
|
||
|
Assert (1, v5[1], "#5a");
|
||
|
|
||
|
d = "aa";
|
||
|
bool b = false;
|
||
|
var r = b ? d : "ss";
|
||
|
Assert ("ss", r, "#6");
|
||
|
|
||
|
var v = new [] { d, 1 };
|
||
|
Assert ("aa", v [0], "#7");
|
||
|
|
||
|
dynamic [,] a = new dynamic [,] { { 1, 2 }, { 'b', 'x' } };
|
||
|
Assert (2, a [0, 1], "#8");
|
||
|
Assert ('x', a [1, 1], "#8a");
|
||
|
}
|
||
|
|
||
|
int ConvertImplicitReturnTest ()
|
||
|
{
|
||
|
dynamic d = (byte) 3;
|
||
|
return d;
|
||
|
}
|
||
|
|
||
|
IEnumerable<string> ConvertImplicitReturnTest_2 ()
|
||
|
{
|
||
|
dynamic d = "aaa";
|
||
|
yield return d;
|
||
|
}
|
||
|
|
||
|
void ConvertExplicitTest ()
|
||
|
{
|
||
|
dynamic d = 300;
|
||
|
Assert (44, (byte) d, "#1");
|
||
|
Assert<byte?> (44, (byte?) d, "#1a");
|
||
|
|
||
|
d = 3m;
|
||
|
Assert (3, d, "#2");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
Assert (5, (int) d, "#3");
|
||
|
|
||
|
d = new MyTypeExplicit (-2);
|
||
|
Assert (-2, (int) d, "#4");
|
||
|
|
||
|
d = null;
|
||
|
Assert (null, (object) d, "#5");
|
||
|
}
|
||
|
|
||
|
void ConvertExplicitCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 300;
|
||
|
AssertChecked (() => (byte) d, 7, "#1");
|
||
|
|
||
|
d = ulong.MaxValue;
|
||
|
AssertChecked<uint?> (() => (uint?) d, 2, "#2");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ConvertArray ()
|
||
|
{
|
||
|
dynamic idx = (uint) 1;
|
||
|
var arr = new int [5];
|
||
|
arr [idx] = 2;
|
||
|
Assert (2, arr [idx], "#1");
|
||
|
}
|
||
|
|
||
|
void EqualTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d == v, false, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d == v2, true, "#1a");
|
||
|
|
||
|
d = true;
|
||
|
Assert (d == false, false, "#2");
|
||
|
bool b2 = true;
|
||
|
Assert (d == b2, true, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d == v3, true, "#3");
|
||
|
dynamic d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 == 11, false, "#3b");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d == v4, false, "#4");
|
||
|
Assert (d == 2m, true, "#4a");
|
||
|
|
||
|
d = null;
|
||
|
Assert (d == null, true, "#5");
|
||
|
}
|
||
|
|
||
|
void EqualNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d == v2, false, "#1");
|
||
|
Assert (d == null, false, "#1a");
|
||
|
Assert (null == d, false, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d == v2, false, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 == 1, false, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 == 44, true, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d == v3, true, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 == new MyType (6), false, "#3a");
|
||
|
Assert (d3 == null, false, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d == v4, false, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d == v4, false, "#4a");
|
||
|
|
||
|
d = (bool?) true;
|
||
|
Assert (d == true, true, "#5");
|
||
|
Assert (d == null, false, "#5a");
|
||
|
Assert (d == false, false, "#5b");
|
||
|
}
|
||
|
|
||
|
void EqualEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d == null, false, "#1");
|
||
|
|
||
|
Assert (d == MyEnum.Value_1, true, "#2");
|
||
|
Assert (d == 0, false, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 == MyEnumUlong.Value_2, true, "#3");
|
||
|
Assert (d2 == null, false, "#3a");
|
||
|
}
|
||
|
|
||
|
void EqualStringTest ()
|
||
|
{
|
||
|
dynamic d = "text";
|
||
|
|
||
|
Assert (d == "te", false, "#1");
|
||
|
Assert (d == "text", true, "#1a");
|
||
|
Assert (d == null, false, "#1b");
|
||
|
}
|
||
|
|
||
|
void EqualDelegateTest ()
|
||
|
{
|
||
|
dynamic d = this;
|
||
|
|
||
|
// Assert (d == delegate { }, true, "#1");
|
||
|
|
||
|
EmptyDelegate b = EqualDelegateTest;
|
||
|
d = b;
|
||
|
|
||
|
//Assert (d == EqualDelegateTest, true, "#2");
|
||
|
|
||
|
/*
|
||
|
|
||
|
void EqualTestDelegate_2 ()
|
||
|
{
|
||
|
EmptyDelegate ed = delegate () {};
|
||
|
|
||
|
Expression<Func<EmptyDelegate, EmptyDelegate, bool>> e2 = (a, b) => a == b;
|
||
|
AssertNodeType (e2, ExpressionType.Equal);
|
||
|
Assert (false, e2.Compile ().Invoke (delegate () {}, null));
|
||
|
Assert (false, e2.Compile ().Invoke (delegate () {}, delegate {}));
|
||
|
Assert (false, e2.Compile ().Invoke (ed, delegate {}));
|
||
|
Assert (true, e2.Compile ().Invoke (ed, ed));
|
||
|
*/
|
||
|
}
|
||
|
|
||
|
void ExclusiveOrTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
Assert (d ^ v, true, "#1");
|
||
|
Assert (d ^ true, false, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
Assert (d ^ v2, 20, "#2");
|
||
|
Assert (d ^ 0, 42, "#2a");
|
||
|
|
||
|
d = new MyType (42);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d ^ v3, new MyType (52), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 ^ new MyType (6), new MyType (-1), "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 ^ 11, -14, "#3b");
|
||
|
}
|
||
|
|
||
|
void ExclusiveOrNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d ^ v2, null, "#1");
|
||
|
Assert<int?> (d ^ null, null, "#1a");
|
||
|
Assert<int?> (null ^ d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d ^ v2, -5, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 ^ 1, -1, "#2a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d ^ v3, new MyType (27), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 ^ new MyType (6), new MyType (-1), "#3a");
|
||
|
Assert<MyType?> (d3 ^ null, null, "#3b");
|
||
|
}
|
||
|
|
||
|
void ExclusiveOrTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert<MyEnum?> (d ^ null, null, "#1");
|
||
|
|
||
|
Assert<MyEnum> (d ^ d, 0, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert<MyEnumUlong> (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
|
||
|
}
|
||
|
|
||
|
void ExclusiveOrAssignedTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
d ^= v;
|
||
|
Assert (d, true, "#1");
|
||
|
d = true;
|
||
|
d ^= true;
|
||
|
Assert (d, false, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
d ^= v2;
|
||
|
Assert (d, 20, "#2");
|
||
|
|
||
|
MyType v3 = new MyType (30);
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 ^= new MyType (6);
|
||
|
Assert (d3, new MyType (-1), "#3");
|
||
|
}
|
||
|
|
||
|
void ExclusiveOrAssignedTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
d ^= MyEnum.Value_2;
|
||
|
Assert<MyEnum>(d, (MyEnum) 3, "#1");
|
||
|
|
||
|
d = MyEnum.Value_2;
|
||
|
d ^= d;
|
||
|
Assert<MyEnum> (d, 0, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert (d2 ^ MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
|
||
|
}
|
||
|
|
||
|
void GreaterThanTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d > v, true, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d > v2, false, "#1a");
|
||
|
|
||
|
d = 4.6;
|
||
|
Assert (d > 4.59, true, "#2");
|
||
|
var b2 = 4.6;
|
||
|
Assert (d > b2, false, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d > v3, false, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 > new MyType (6), false, "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 > 11, false, "#3b");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d > v4, false, "#4");
|
||
|
Assert (d > 2m, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void GreaterThanNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d > v2, false, "#1");
|
||
|
Assert (d > null, false, "#1a");
|
||
|
Assert (null > d, false, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d > v2, true, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 > 1, false, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 > 44, false, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d > v3, false, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 > new MyType (6), false, "#3a");
|
||
|
Assert (d3 > null, false, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d > v4, true, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d > v4, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void GreaterThanEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d > null, false, "#1");
|
||
|
|
||
|
Assert (d > MyEnum.Value_1, false, "#2");
|
||
|
Assert (d > 0, true, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 > MyEnumUlong.Value_2, false, "#3");
|
||
|
Assert (d2 > null, false, "#3a");
|
||
|
}
|
||
|
|
||
|
void GreaterThanEqualTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d >= v, true, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d >= v2, true, "#1a");
|
||
|
|
||
|
d = 4.6;
|
||
|
Assert (d >= 4.59, true, "#2");
|
||
|
var b2 = 4.6;
|
||
|
Assert (d >= b2, true, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d >= v3, true, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 >= new MyType (6), false, "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 >= 11, false, "#3b");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d >= v4, false, "#4");
|
||
|
Assert (d >= 2m, true, "#4a");
|
||
|
}
|
||
|
|
||
|
void GreaterThanEqualNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d >= v2, false, "#1");
|
||
|
Assert (d >= null, false, "#1a");
|
||
|
Assert (null >= d, false, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d >= v2, true, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 >= 1, false, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 >= 44, true, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d >= v3, true, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 >= new MyType (6), false, "#3a");
|
||
|
Assert (d3 >= null, false, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d >= v4, true, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d >= v4, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void GreaterThanEqualEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d >= null, false, "#1");
|
||
|
|
||
|
Assert (d >= MyEnum.Value_1, true, "#2");
|
||
|
Assert (d >= 0, true, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 >= MyEnumUlong.Value_2, true, "#3");
|
||
|
Assert (d2 >= null, false, "#3a");
|
||
|
}
|
||
|
|
||
|
void IsTest ()
|
||
|
{
|
||
|
dynamic d = 1;
|
||
|
Assert (d is long, false, "#1");
|
||
|
Assert (d is int, true, "#2");
|
||
|
Assert (d is string, false, "#3");
|
||
|
}
|
||
|
|
||
|
void LeftShiftTest ()
|
||
|
{
|
||
|
dynamic d = (ulong) 0x7F000;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert<ulong> (d << v, 0x1FC000, "#1");
|
||
|
Assert<ulong> (d << 1, 0xFE000, "#1a");
|
||
|
short s = 2;
|
||
|
Assert<ulong> (d << s, 0x1FC000, "#1b");
|
||
|
|
||
|
d = 0x7F000;
|
||
|
MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
|
||
|
Assert (d << v3, 0x3F8000, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 << new MyTypeImplicitOnly (6), -448, "#3a");
|
||
|
Assert (d3 << 11, -14336, "#3b");
|
||
|
}
|
||
|
|
||
|
void LeftShiftNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d << v2, null, "#1");
|
||
|
d = 5;
|
||
|
Assert<int?> (d << null, null, "#1a");
|
||
|
d = 5;
|
||
|
Assert<int?> (null << d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d << v2, 0x40000000, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 << 1, -4, "#2a");
|
||
|
|
||
|
dynamic d3 = (int?) null;
|
||
|
Assert (d3 << (null << null), (int?)null, "#3");
|
||
|
}
|
||
|
|
||
|
void LeftShiftAssignTest ()
|
||
|
{
|
||
|
dynamic d = 0x7F000;
|
||
|
|
||
|
int v = 2;
|
||
|
d <<= v;
|
||
|
Assert (d, 0x1FC000, "#1");
|
||
|
d <<= 1;
|
||
|
Assert (d, 0x3F8000, "#1a");
|
||
|
sbyte s = 2;
|
||
|
d <<= s;
|
||
|
Assert (d, 0xFE0000, "#1b");
|
||
|
}
|
||
|
|
||
|
void LeftShiftAssignNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
var v2 = -2;
|
||
|
d <<= v2;
|
||
|
Assert (d, 0x40000000, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
d2 <<= 1;
|
||
|
Assert (d2, -4, "#2a");
|
||
|
}
|
||
|
|
||
|
void LessThanTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d < v, false, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d < v2, false, "#1a");
|
||
|
|
||
|
d = 4.6;
|
||
|
Assert (d < 4.59, false, "#2");
|
||
|
var b2 = 4.6;
|
||
|
Assert (d < b2, false, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d < v3, false, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 < new MyType (6), true, "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 < 11, true, "#3b");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d < v4, true, "#4");
|
||
|
Assert (d < 2m, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void LessThanNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d < v2, false, "#1");
|
||
|
Assert (d < null, false, "#1a");
|
||
|
Assert (null < d, false, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d < v2, false, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 < 1, true, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 < 44, false, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d < v3, false, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 < new MyType (6), true, "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 < null, false, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d < v4, false, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d < v4, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void LessThanEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d < null, false, "#1");
|
||
|
|
||
|
Assert (d < MyEnum.Value_1, false, "#2");
|
||
|
Assert (d < 0, false, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 < MyEnumUlong.Value_2, false, "#3");
|
||
|
Assert (d2 < null, false, "#3a");
|
||
|
}
|
||
|
|
||
|
void LessThanOrEqualTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d <= v, false, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d <= v2, true, "#1a");
|
||
|
|
||
|
d = 4.6;
|
||
|
Assert (d <= 4.59, false, "#2");
|
||
|
var b2 = 4.6;
|
||
|
Assert (d <= b2, true, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d <= v3, true, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 <= new MyType (6), true, "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 <= 11, true, "#3b");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d <= v4, true, "#4");
|
||
|
Assert (d <= 2m, true, "#4a");
|
||
|
}
|
||
|
|
||
|
void LessThanOrEqualNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d <= v2, false, "#1");
|
||
|
Assert (d <= null, false, "#1a");
|
||
|
Assert (null <= d, false, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d <= v2, false, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 <= 1, true, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 <= 44, true, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d <= v3, true, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 <= new MyType (6), true, "#3a");
|
||
|
Assert (d3 <= null, false, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d <= v4, false, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d <= v4, false, "#4a");
|
||
|
}
|
||
|
|
||
|
void LessThanOrEqualEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d <= null, false, "#1");
|
||
|
|
||
|
Assert (d <= MyEnum.Value_1, true, "#2");
|
||
|
Assert (d <= 0, false, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 <= MyEnumUlong.Value_2, true, "#3");
|
||
|
Assert (d2 <= null, false, "#3a");
|
||
|
}
|
||
|
|
||
|
void ModuloTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d % v, 1, "#1");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d % v3, new MyType (5), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 % new MyType (6), new MyType (-1), "#3a");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d % v4, 1m, "#4");
|
||
|
}
|
||
|
|
||
|
void ModuloNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
double? v2 = null;
|
||
|
Assert<double?> (d % v2, null, "#1");
|
||
|
Assert<double?> (d % null, null, "#1a");
|
||
|
Assert<double?> (null % d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d % v2, 1, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 % 1, 0, "#2a");
|
||
|
|
||
|
d = new MyType (-2);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d % v3, new MyType (-2), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 % new MyType (6), new MyType (-1), "#3a");
|
||
|
Assert<MyType?> (d3 + null, null, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d % v4, 1m, "#4");
|
||
|
v4 = null;
|
||
|
Assert<decimal?> (d % v4, null, "#4a");
|
||
|
}
|
||
|
|
||
|
void ModuloAssignTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
d %= v;
|
||
|
Assert (d, 1, "#1");
|
||
|
|
||
|
d = 5.0;
|
||
|
double v2 = 0.5;
|
||
|
d %= v2;
|
||
|
Assert (d, 0, "#1a");
|
||
|
d %= v;
|
||
|
Assert (d, 0, "#1b");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 %= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-1), "#3");
|
||
|
|
||
|
d = 5m;
|
||
|
decimal v4 = 4m;
|
||
|
d %= v4;
|
||
|
Assert (d, 1m, "#4");
|
||
|
}
|
||
|
|
||
|
void MultiplyTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d * v, 10, "#1");
|
||
|
double v2 = 0.5;
|
||
|
Assert (d * v2, 2.5, "#1a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d * v3, new MyType (150), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 * new MyType (6), new MyType (-42), "#3a");
|
||
|
|
||
|
decimal v4 = 4m;
|
||
|
d = 7.9m;
|
||
|
Assert (d * v4, 31.6m, "#4");
|
||
|
}
|
||
|
|
||
|
void MultiplyNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d * v2, null, "#1");
|
||
|
Assert<int?> (d * null, null, "#1a");
|
||
|
Assert<int?> (null * d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d * v2, -10, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 * 1, -2, "#2a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d * v3, new MyType (150), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 * new MyType (6), new MyType (-42), "#3a");
|
||
|
Assert<MyType?> (d3 * null, null, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d * v4, 20m, "#4");
|
||
|
v4 = null;
|
||
|
Assert<decimal?> (d * v4, null, "#4a");
|
||
|
}
|
||
|
|
||
|
void MultiplyCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MaxValue;
|
||
|
AssertChecked (() => d * v, 7, "#1");
|
||
|
|
||
|
int? v2 = v;
|
||
|
AssertChecked (() => d * v2, null, "#2");
|
||
|
|
||
|
d = new MyType (4);
|
||
|
MyType v3 = new MyType (int.MaxValue);
|
||
|
Assert (d * v3, new MyType (-4), "#3");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void MultiplyAssignTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
d *= v;
|
||
|
Assert (d, 10, "#1");
|
||
|
|
||
|
d = 5.0;
|
||
|
double v2 = 0.5;
|
||
|
d *= v2;
|
||
|
Assert (d, 2.5, "#1a");
|
||
|
d *= v;
|
||
|
Assert (d, 5, "#1b");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 *= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-42), "#3");
|
||
|
|
||
|
d = 5m;
|
||
|
decimal v4 = 4m;
|
||
|
d *= v4;
|
||
|
Assert (d, 20m, "#4");
|
||
|
|
||
|
int i = 3;
|
||
|
d = 5;
|
||
|
i *= d;
|
||
|
Assert (i, 15, "#5");
|
||
|
}
|
||
|
|
||
|
void MultiplyAssignCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MaxValue;
|
||
|
AssertChecked (() => { d *= v; Assert (d, 0, "#1-"); }, "#1");
|
||
|
|
||
|
d = new MyType (44);
|
||
|
MyType v3 = new MyType (int.MaxValue);
|
||
|
d *= v3;
|
||
|
Assert (d, new MyType (-44), "#3-");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Negate ()
|
||
|
{
|
||
|
dynamic d = -8;
|
||
|
Assert (8, -d, "#1");
|
||
|
Assert (-8, -(-d), "#1a");
|
||
|
|
||
|
d = new MyType (-14);
|
||
|
Assert (new MyType (14), -d, "#2");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (4);
|
||
|
Assert (-4, -d, "#3");
|
||
|
|
||
|
d = (uint) 7;
|
||
|
Assert (-7, -d, "#4");
|
||
|
|
||
|
d = double.NegativeInfinity;
|
||
|
Assert (double.PositiveInfinity, -d, "#5");
|
||
|
}
|
||
|
|
||
|
void NegateNullable ()
|
||
|
{
|
||
|
dynamic d = (int?) -8;
|
||
|
Assert (8, -d, "#1");
|
||
|
Assert (-8, -(-d), "#1a");
|
||
|
|
||
|
MyType? n1 = new MyType (4);
|
||
|
d = n1;
|
||
|
Assert (new MyType (-4), -d, "#2");
|
||
|
|
||
|
MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
|
||
|
d = n2;
|
||
|
Assert (-4, -d, "#3");
|
||
|
|
||
|
d = (sbyte?) 7;
|
||
|
Assert (-7, -d, "#4");
|
||
|
}
|
||
|
|
||
|
void NegateChecked ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = int.MinValue;
|
||
|
AssertChecked (() => -d, 0, "#1");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Not ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
Assert (false, !d, "#1");
|
||
|
|
||
|
var de = new MyType (-1);
|
||
|
Assert (false, !d, "#2");
|
||
|
}
|
||
|
|
||
|
void NotEqualTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d != v, true, "#1");
|
||
|
double v2 = 5;
|
||
|
Assert (d != v2, false, "#1a");
|
||
|
|
||
|
d = true;
|
||
|
Assert (d != false, true, "#2");
|
||
|
bool b2 = true;
|
||
|
Assert (d != b2, false, "#2a");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d != v3, false, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 != new MyType (6), true, "#3a");
|
||
|
|
||
|
d = 2m;
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d != v4, true, "#4");
|
||
|
Assert (d != 2m, false, "#4a");
|
||
|
|
||
|
d = null;
|
||
|
Assert (d != null, false, "#5");
|
||
|
}
|
||
|
|
||
|
void NotEqualNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert (d != v2, true, "#1");
|
||
|
Assert (d != null, true, "#1a");
|
||
|
Assert (null != d, true, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d != v2, true, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 != 1, true, "#2a");
|
||
|
d2 = (uint?) 44;
|
||
|
Assert (d2 != 44, false, "#2b");
|
||
|
|
||
|
d = new MyType (30);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d != v3, false, "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 != new MyType (6), true, "#3a");
|
||
|
Assert (d3 != null, true, "#3b");
|
||
|
|
||
|
d = 4.1m;
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d != v4, true, "#4");
|
||
|
v4 = null;
|
||
|
Assert (d != v4, true, "#4a");
|
||
|
|
||
|
d = (bool?) true;
|
||
|
Assert (d != true, false, "#5");
|
||
|
Assert (d != null, true, "#5a");
|
||
|
Assert (d != false, true, "#5b");
|
||
|
|
||
|
d = null;
|
||
|
long? l = null;
|
||
|
Assert (d != l, false, "#6a");
|
||
|
Assert (l != d, false, "#6b");
|
||
|
}
|
||
|
|
||
|
void NotEqualEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert (d != null, true, "#1");
|
||
|
|
||
|
Assert (d != MyEnum.Value_1, false, "#2");
|
||
|
Assert (d != 0, true, "#2a");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 != MyEnumUlong.Value_2, false, "#3");
|
||
|
Assert (d2 != null, true, "#3a");
|
||
|
}
|
||
|
|
||
|
void NotEqualStringTest ()
|
||
|
{
|
||
|
dynamic d = "text";
|
||
|
|
||
|
Assert (d != "te", true, "#1");
|
||
|
Assert (d != "text", false, "#1a");
|
||
|
Assert (d != null, true, "#1b");
|
||
|
}
|
||
|
|
||
|
void OnesComplement ()
|
||
|
{
|
||
|
dynamic d = 7;
|
||
|
Assert (-8, ~d, "#1");
|
||
|
|
||
|
d = new MyType (-1);
|
||
|
Assert (0, ~d, "#2");
|
||
|
|
||
|
d = (ulong) 7;
|
||
|
Assert (18446744073709551608, ~d, "#3");
|
||
|
|
||
|
d = MyEnum.Value_1;
|
||
|
Assert ((MyEnum) 254, ~d, "#4");
|
||
|
}
|
||
|
|
||
|
void OnesComplementNullable ()
|
||
|
{
|
||
|
dynamic d = (int?) 7;
|
||
|
Assert (-8, ~d, "#1");
|
||
|
|
||
|
d = (MyEnum?) MyEnum.Value_1;
|
||
|
Assert ((MyEnum) 254, ~d, "#4");
|
||
|
}
|
||
|
|
||
|
void OrTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
Assert (d | v, true, "#1");
|
||
|
Assert (d | false, true, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
Assert (d | v2, 62, "#2");
|
||
|
Assert (d | 0, 42, "#2a");
|
||
|
|
||
|
d = new MyType (42);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d | v3, new MyType (62), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 | new MyType (6), new MyType (-1), "#3a");
|
||
|
|
||
|
d3 = new MyTypeImplicitOnly (-7);
|
||
|
Assert (d3 | 11, -5, "#3b");
|
||
|
}
|
||
|
|
||
|
void OrTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert<MyEnum?> (d | null, null, "#1");
|
||
|
|
||
|
Assert (d | d, MyEnum.Value_1, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong) 3, "#3");
|
||
|
}
|
||
|
|
||
|
void OrTestNullable ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d | v2, null, "#1");
|
||
|
Assert<int?> (d | null, null, "#1a");
|
||
|
Assert<int?> (null | d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d | v2, -1, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 | 1, -1, "#2a");
|
||
|
|
||
|
d = new MyType (-2);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d | v3, new MyType (-2), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 | new MyType (6), new MyType (-1), "#3a");
|
||
|
}
|
||
|
|
||
|
void OrAssignedTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
d |= v;
|
||
|
Assert (d, true, "#1");
|
||
|
d = true;
|
||
|
d |= true;
|
||
|
Assert (d, true, "#1a");
|
||
|
|
||
|
d = 42;
|
||
|
var v2 = 62;
|
||
|
d |= v2;
|
||
|
Assert (d, 62, "#2");
|
||
|
|
||
|
MyType v3 = new MyType (30);
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 |= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-1), "#3");
|
||
|
}
|
||
|
|
||
|
void OrAssignedTestEnum ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
d |= MyEnum.Value_2;
|
||
|
Assert<MyEnum> (d, (MyEnum) 3, "#1");
|
||
|
|
||
|
d = MyEnum.Value_2;
|
||
|
d |= d;
|
||
|
Assert (d, MyEnum.Value_2, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_1;
|
||
|
Assert<MyEnumUlong> (d2 | MyEnumUlong.Value_2, (MyEnumUlong)3, "#3");
|
||
|
}
|
||
|
|
||
|
void OrElseTest ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
|
||
|
var v = false;
|
||
|
Assert<bool> (d || v, true, "#1");
|
||
|
|
||
|
Assert (d || true, true, "#1a");
|
||
|
|
||
|
d = true;
|
||
|
Assert (d || d, true, "#2");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert<MyType> (d3 || new MyType (6), new MyType (-7), "#3");
|
||
|
}
|
||
|
|
||
|
void RightShiftTest ()
|
||
|
{
|
||
|
dynamic d = (ulong) 0x7F000;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert<ulong> (d >> v, 0x1FC00, "#1");
|
||
|
Assert<ulong> (d >> 1, 0x3F800, "#1a");
|
||
|
short s = 2;
|
||
|
Assert<ulong> (d >> s, 0x1FC00, "#1b");
|
||
|
|
||
|
d = 0x7F000;
|
||
|
MyTypeImplicitOnly v3 = new MyTypeImplicitOnly (3);
|
||
|
Assert (d >> v3, 0xFE00, "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 >> new MyTypeImplicitOnly (11), -1, "#3a");
|
||
|
}
|
||
|
|
||
|
void RightShiftNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d >> v2, null, "#1");
|
||
|
d = 5;
|
||
|
Assert<int?> (d >> null, null, "#1a");
|
||
|
d = 5;
|
||
|
Assert<int?> (null >> d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d >> v2, 0, "#2");
|
||
|
dynamic d2 = (int?) -200;
|
||
|
Assert (d2 >> 1, -100, "#2a");
|
||
|
|
||
|
dynamic d3 = (int?) null;
|
||
|
Assert (d3 >> (null >> null), (int?) null, "#3");
|
||
|
}
|
||
|
|
||
|
void RightShiftAssignTest ()
|
||
|
{
|
||
|
dynamic d = 0x7F000;
|
||
|
|
||
|
int v = 2;
|
||
|
d >>= v;
|
||
|
Assert (d, 0x1FC00, "#1");
|
||
|
d >>= 1;
|
||
|
Assert (d, 0xFE00, "#1a");
|
||
|
sbyte s = 2;
|
||
|
d >>= s;
|
||
|
Assert (d, 0x3F80, "#1b");
|
||
|
}
|
||
|
|
||
|
void RightShiftAssignNullableTest ()
|
||
|
{
|
||
|
dynamic d = 0x2A0;
|
||
|
|
||
|
var v2 = -2;
|
||
|
d >>= v2;
|
||
|
Assert (d, 0, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
d2 >>= 1;
|
||
|
Assert (d2, -1, "#2a");
|
||
|
}
|
||
|
|
||
|
void SubtractTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
Assert (d - v, 3, "#1");
|
||
|
double v2 = 0.5;
|
||
|
Assert (d - v2, 4.5, "#1a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (30);
|
||
|
Assert (d - v3, new MyType (-25), "#3");
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
Assert (d3 - new MyType (6), new MyType (-13), "#3a");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal v4 = 4m;
|
||
|
Assert (d - v4, 1m, "#4");
|
||
|
}
|
||
|
|
||
|
void SubtractNullableTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int? v2 = null;
|
||
|
Assert<int?> (d - v2, null, "#1");
|
||
|
Assert<int?> (d - null, null, "#1a");
|
||
|
Assert<int?> (null - d, null, "#1b");
|
||
|
|
||
|
v2 = -2;
|
||
|
Assert (d - v2, 7, "#2");
|
||
|
dynamic d2 = (int?) -2;
|
||
|
Assert (d2 - 1, -3, "#2a");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType? v3 = new MyType (30);
|
||
|
Assert (d - v3, new MyType (-25), "#3");
|
||
|
dynamic d3 = new MyType? (new MyType (-7));
|
||
|
Assert (d3 - new MyType (6), new MyType (-13), "#3a");
|
||
|
Assert<MyType?> (d3 - null, null, "#3b");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (5);
|
||
|
decimal? v4 = 4m;
|
||
|
Assert (d - v4, 1m, "#4");
|
||
|
v4 = null;
|
||
|
Assert<decimal?> (d - v4, null, "#4a");
|
||
|
}
|
||
|
|
||
|
void SubtractEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
Assert<MyEnum> (d - 1, 0, "#1");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
Assert (d2 - (byte) 1, MyEnumUlong.Value_1, "#2");
|
||
|
Assert<MyEnumUlong?> (d2 - null, null, "#2a");
|
||
|
|
||
|
// CSC: Invalid System.InvalidOperationException
|
||
|
Assert<MyEnum?> (d - null, null, "#3");
|
||
|
}
|
||
|
|
||
|
void SubtractCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MinValue;
|
||
|
AssertChecked (() => d - v, 7, "#1");
|
||
|
|
||
|
int? v2 = v;
|
||
|
AssertChecked (() => d - v2, null, "#2");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (int.MinValue);
|
||
|
Assert (d - v3, new MyType (-2147483643), "#3");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SubtractAssignTest ()
|
||
|
{
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = 2;
|
||
|
d -= v;
|
||
|
Assert (d, 3, "#1");
|
||
|
|
||
|
d = 5.0;
|
||
|
double v2 = 0.5;
|
||
|
d -= v2;
|
||
|
Assert (d, 4.5, "#1a");
|
||
|
d -= v;
|
||
|
Assert (d, 2.5, "#1b");
|
||
|
|
||
|
dynamic d3 = new MyType (-7);
|
||
|
d3 -= new MyType (6);
|
||
|
Assert<MyType> (d3, new MyType (-13), "#3");
|
||
|
|
||
|
d = 5m;
|
||
|
decimal v4 = 4m;
|
||
|
d -= v4;
|
||
|
Assert (d, 1m, "#4");
|
||
|
}
|
||
|
|
||
|
void SubtractAssignEnumTest ()
|
||
|
{
|
||
|
dynamic d = MyEnum.Value_1;
|
||
|
|
||
|
d -= 1;
|
||
|
Assert<MyEnum> (d, 0, "#2");
|
||
|
|
||
|
dynamic d2 = (MyEnumUlong?) MyEnumUlong.Value_2;
|
||
|
d2 -= (byte) 1;
|
||
|
Assert (d2, MyEnumUlong.Value_1, "#3");
|
||
|
}
|
||
|
|
||
|
void SubtractAssignCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = 5;
|
||
|
|
||
|
int v = int.MinValue;
|
||
|
AssertChecked (() => { d -= v; Assert (d, 0, "#1a"); }, "#1");
|
||
|
|
||
|
d = new MyType (5);
|
||
|
MyType v3 = new MyType (int.MinValue);
|
||
|
d -= v3;
|
||
|
Assert (d, new MyType (-2147483643), "#3a");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void SubtractAssignEvent ()
|
||
|
{
|
||
|
Action print = () => { Console.WriteLine ("foo"); };
|
||
|
dynamic d = print;
|
||
|
|
||
|
// FIXME: Will have to special case events
|
||
|
//ev_assign -= d;
|
||
|
//ev_assign ();
|
||
|
}
|
||
|
|
||
|
void UnaryDecrement ()
|
||
|
{
|
||
|
dynamic d = 3;
|
||
|
Assert (3, d--, "#1");
|
||
|
Assert (2, d, "#1a");
|
||
|
|
||
|
d = 3;
|
||
|
Assert (2, --d, "#2");
|
||
|
Assert (2, d, "#2a");
|
||
|
|
||
|
d = new MyType (-3);
|
||
|
Assert (new MyType (-3), d--, "#3");
|
||
|
Assert (new MyType (-1), d, "#3a");
|
||
|
}
|
||
|
|
||
|
void UnaryDecrementCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = int.MinValue;
|
||
|
|
||
|
AssertChecked (() => { d--; Assert (d, -1073741824, "#1a"); }, "#1");
|
||
|
|
||
|
d = new MyType (int.MinValue);
|
||
|
d--;
|
||
|
Assert (d, new MyType (-1073741824), "#2");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void UnaryIncrement ()
|
||
|
{
|
||
|
dynamic d = 3;
|
||
|
Assert (3, d++, "#1");
|
||
|
Assert (4, d, "#1a");
|
||
|
|
||
|
d = 3;
|
||
|
Assert (4, ++d, "#2");
|
||
|
Assert (4, d, "#2a");
|
||
|
|
||
|
d = new MyType (-3);
|
||
|
Assert (new MyType (-3), d++, "#3");
|
||
|
Assert (new MyType (-6), d, "#3a");
|
||
|
}
|
||
|
|
||
|
void UnaryIncrementCheckedTest ()
|
||
|
{
|
||
|
checked {
|
||
|
dynamic d = int.MaxValue;
|
||
|
|
||
|
AssertChecked (() => { d++; Assert (d, 0, "#1a"); }, "#1");
|
||
|
|
||
|
d = new MyType (int.MaxValue);
|
||
|
d++;
|
||
|
Assert (d, new MyType (-2), "#2");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//void UnaryIsFalse ()
|
||
|
//{
|
||
|
// dynamic d = this;
|
||
|
// object r = d == null;
|
||
|
// Assert (false, (bool) r, "#1");
|
||
|
// Assert<object> (true, d != null, "#1a");
|
||
|
//}
|
||
|
|
||
|
void UnaryIsTrue ()
|
||
|
{
|
||
|
dynamic d = true;
|
||
|
Assert (3, d ? 3 : 5, "#1");
|
||
|
|
||
|
d = 4;
|
||
|
Assert (false, d < 1, "#2");
|
||
|
|
||
|
d = new InverseLogicalOperator (true);
|
||
|
Assert (1, d ? 1 : -1, "#3");
|
||
|
}
|
||
|
|
||
|
void UnaryPlus ()
|
||
|
{
|
||
|
dynamic d = -8;
|
||
|
Assert (-8, +d, "#1");
|
||
|
Assert (-8, +(+d), "#1a");
|
||
|
|
||
|
d = new MyType (14);
|
||
|
Assert (new MyType (334455), +d, "#2");
|
||
|
|
||
|
d = new MyTypeImplicitOnly (4);
|
||
|
Assert (4, +d, "#3");
|
||
|
|
||
|
d = (uint) 7;
|
||
|
Assert<uint> (7, +d, "#4");
|
||
|
}
|
||
|
|
||
|
void UnaryPlusNullable ()
|
||
|
{
|
||
|
dynamic d = (int?) -8;
|
||
|
Assert (-8, +d, "#1");
|
||
|
Assert (-8, +(+d), "#1a");
|
||
|
|
||
|
MyType? n1 = new MyType (4);
|
||
|
d = n1;
|
||
|
Assert (new MyType (334455), +d, "#2");
|
||
|
|
||
|
MyTypeImplicitOnly? n2 = new MyTypeImplicitOnly (4);
|
||
|
d = n2;
|
||
|
Assert (4, +d, "#3");
|
||
|
|
||
|
d = (sbyte?) 7;
|
||
|
Assert (7, +d, "#4");
|
||
|
}
|
||
|
|
||
|
#pragma warning restore 169
|
||
|
|
||
|
static bool RunTest (MethodInfo test)
|
||
|
{
|
||
|
Console.Write ("Running test {0, -25}", test.Name);
|
||
|
try {
|
||
|
test.Invoke (new Tester (), null);
|
||
|
Console.WriteLine ("OK");
|
||
|
return true;
|
||
|
} catch (Exception e) {
|
||
|
Console.WriteLine ("FAILED");
|
||
|
Console.WriteLine (e.ToString ());
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static int Main ()
|
||
|
{
|
||
|
var tests = from test in typeof (Tester).GetMethods (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
|
||
|
where test.GetParameters ().Length == 0
|
||
|
orderby test.Name
|
||
|
select RunTest (test);
|
||
|
|
||
|
int failures = tests.Count (a => !a);
|
||
|
Console.WriteLine (failures + " tests failed");
|
||
|
return failures;
|
||
|
}
|
||
|
}
|
||
|
|