Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Tests for operators on type CS type with codec
  • Loading branch information
gertdreyer committed Feb 23, 2024
commit 5d551fbfe1897f4ede46d89a0dbe27553d255d1b
230 changes: 230 additions & 0 deletions src/embed_tests/TestOperator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class TestOperator
public void SetUp()
{
PythonEngine.Initialize();
OwnIntCodec.Setup();
}

[OneTimeTearDown]
Expand All @@ -23,6 +24,120 @@ public void Dispose()
PythonEngine.Shutdown();
}

// Mock Integer class to test math ops on non-native dotnet types
public struct OwnInt
Comment thread
gertdreyer marked this conversation as resolved.
Outdated
{
private int _value;

public int Num => _value;

public OwnInt()
{
_value = 0;
}

public OwnInt(int value)
{
_value = value;
}

public static OwnInt operator -(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value - p2._value);
}

public static OwnInt operator +(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value + p2._value);
}

public static OwnInt operator *(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value * p2._value);
}

public static OwnInt operator /(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value / p2._value);
}

public static OwnInt operator %(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value % p2._value);
}

public static OwnInt operator ^(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value ^ p2._value);
}

public static bool operator <(OwnInt p1, OwnInt p2)
{
return p1._value < p2._value;
}

public static bool operator >(OwnInt p1, OwnInt p2)
{
return p1._value > p2._value;
}

public static bool operator ==(OwnInt p1, OwnInt p2)
{
return p1._value == p2._value;
}

public static bool operator !=(OwnInt p1, OwnInt p2)
{
return p1._value != p2._value;
}

public static OwnInt operator |(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value | p2._value);
}

public static OwnInt operator &(OwnInt p1, OwnInt p2)
{
return new OwnInt(p1._value & p2._value);
}

public static bool operator <=(OwnInt p1, OwnInt p2)
{
return p1._value <= p2._value;
}

public static bool operator >=(OwnInt p1, OwnInt p2)
{
return p1._value >= p2._value;
}
}

// Codec for mock class above.
public class OwnIntCodec : IPyObjectDecoder
{
public static void Setup()
{
PyObjectConversions.RegisterDecoder(new OwnIntCodec());
}

public bool CanDecode(PyType objectType, Type targetType)
{
return objectType.Name == "int" && targetType == typeof(OwnInt);
}

public bool TryDecode<T>(PyObject pyObj, out T? value)
Comment thread
gertdreyer marked this conversation as resolved.
Outdated
{
if (pyObj.PyType.Name != "int" || typeof(T) != typeof(OwnInt))
Comment thread
gertdreyer marked this conversation as resolved.
Outdated
{
value = default(T);
return false;
}

value = (T)(object)new OwnInt(pyObj.As<int>());
return true;
}
}

public class OperableObject
{
public int Num { get; set; }
Expand Down Expand Up @@ -524,6 +639,121 @@ public void ShiftOperatorOverloads()

c = a >> b.Num
assert c.Num == a.Num >> b.Num
");
}

[Test]
public void ReverseOperatorWithCodec()
{
string name = string.Format("{0}.{1}",
typeof(OwnInt).DeclaringType.Name,
typeof(OwnInt).Name);
string module = MethodBase.GetCurrentMethod().DeclaringType.Namespace;

PythonEngine.Exec($@"
from {module} import *
cls = {name}
a = 2
b = cls(10)

c = a + b
assert c.Num == a + b.Num

c = a - b
assert c.Num == a - b.Num

c = a * b
assert c.Num == a * b.Num

c = a / b
assert c.Num == a // b.Num

c = a % b
assert c.Num == a % b.Num

c = a & b
assert c.Num == a & b.Num

c = a | b
assert c.Num == a | b.Num

c = a ^ b
assert c.Num == a ^ b.Num

c = a == b
assert c == (a == b.Num)

c = a != b
assert c == (a != b.Num)

c = a <= b
assert c == (a <= b.Num)

c = a >= b
assert c == (a >= b.Num)

c = a < b
assert c == (a < b.Num)

c = a > b
assert c == (a > b.Num)
");
}

[Test]
public void ForwardOperatorWithCodec()
{
string name = string.Format("{0}.{1}",
typeof(OwnInt).DeclaringType.Name,
typeof(OwnInt).Name);
string module = MethodBase.GetCurrentMethod().DeclaringType.Namespace;

PythonEngine.Exec($@"
from {module} import *
cls = {name}
a = cls(2)
b = 10
c = a + b
assert c.Num == a.Num + b

c = a - b
assert c.Num == a.Num - b

c = a * b
assert c.Num == a.Num * b

c = a / b
assert c.Num == a.Num // b

c = a % b
assert c.Num == a.Num % b

c = a & b
assert c.Num == a.Num & b

c = a | b
assert c.Num == a.Num | b

c = a ^ b
assert c.Num == a.Num ^ b

c = a == b
assert c == (a.Num == b)

c = a != b
assert c == (a.Num != b)

c = a <= b
assert c == (a.Num <= b)

c = a >= b
assert c == (a.Num >= b)

c = a < b
assert c == (a.Num < b)

c = a > b
assert c == (a.Num > b)
");
}
}
Expand Down