Skip to content

Commit

Permalink
Add byte.AsString and Map UTs (#303)
Browse files Browse the repository at this point in the history
* add byte.AsString and Map UTs

* fix

* Update src/Neo.SmartContract.Framework/Helper.cs

Co-authored-by: Erik Zhang <[email protected]>

* fix

* fix

* fix Enum and Iterator Test

* update neo

* fix

* fix map key and UT

Co-authored-by: Erik Zhang <[email protected]>
Co-authored-by: Shargon <[email protected]>
  • Loading branch information
3 people authored Jul 16, 2020
1 parent ec552fe commit b143a7d
Show file tree
Hide file tree
Showing 9 changed files with 438 additions and 20 deletions.
2 changes: 2 additions & 0 deletions src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,8 @@ private int ConvertNewObj(ILMethod from, OpCode src, NeoMethod to)
{
throw new Exception("unsupported type:System.Decimal.");
}
if (_type.FullName.Contains("Neo.SmartContract.Framework.Map") && _type.FullName.Contains("<System.Byte[]"))
throw new Exception("The Key of Map cannot be Byte[], it should be PrimitiveType.");
var type = _type.Resolve();
// Replace the New Array operation if there is an [OpCode] on the constructor
foreach (var m in type.DeclaringType.Methods)
Expand Down
5 changes: 3 additions & 2 deletions src/Neo.SmartContract.Framework/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Neo.SmartContract.Framework
public static class Helper
{
internal const string StackItemType_Integer = "0x21";
internal const string StackItemType_ByteString = "0x28";
internal const string StackItemType_Buffer = "0x30";

/// <summary>
Expand Down Expand Up @@ -48,8 +49,8 @@ public static class Helper
/// <summary>
/// Converts byte[] to string. Examples: [0x68656c6c6f] -> "hello"; [] -> ""; [0x4e656f] -> "Neo"
/// </summary>
[Script]
public extern static string AsString(this byte[] source);
[OpCode(OpCode.CONVERT, StackItemType_ByteString)]
public extern static string ToByteString(this byte[] source);

/// <summary>
/// Returns true iff a <= x && x < b. Examples: x=5 a=5 b=15 is true; x=15 a=5 b=15 is false
Expand Down
137 changes: 137 additions & 0 deletions tests/Neo.SmartContract.Framework.UnitTests/MapTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Compiler.MSIL.UnitTests.Utils;
using Neo.VM;
using Neo.VM.Types;

namespace Neo.SmartContract.Framework.UnitTests
{
[TestClass]
public class MapTest
{
private TestEngine _engine;

[TestInitialize]
public void Init()
{
_engine = new TestEngine();
_engine.AddEntryScript("./TestClasses/Contract_Map.cs");
}

[TestMethod]
public void TestByteArrayMap()
{
Assert.ThrowsException<System.Exception>(() => _engine.AddEntryScript("./TestClasses/Contract_MapException.cs"));
}

[TestMethod]
public void TestByteArray()
{
_engine.Reset();
StackItem key = System.Text.Encoding.ASCII.GetBytes("a");
var result = _engine.ExecuteTestCaseStandard("testByteArray", key);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(ByteString));
// Except: {"a":"teststring2"}
Assert.AreEqual("7b2261223a2274657374737472696e6732227d", (item as ByteString).GetSpan().ToHexString());
}

[TestMethod]
public void TestByteArray2()
{
_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testByteArray2");
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(ByteString));
// Except: {"\u0001\u0001":"\u0022\u0022"}
Assert.AreEqual("7b225c75303030315c7530303031223a225c75303032325c7530303232227d", (item as ByteString).GetSpan().ToHexString());
}

[TestMethod]
public void TestUnicode()
{
_engine.Reset();
StackItem key = System.Text.Encoding.UTF8.GetBytes("中");
var result = _engine.ExecuteTestCaseStandard("testUnicode", key);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(ByteString));
// Except: {"\u4E2D":"129840test10022939"}
Assert.AreEqual("7b225c7534453244223a22313239383430746573743130303232393339227d", (item as ByteString).GetSpan().ToHexString());
}

[TestMethod]
public void TestUnicodeValue()
{
_engine.Reset();
StackItem value = System.Text.Encoding.UTF8.GetBytes("文");
var result = _engine.ExecuteTestCaseStandard("testUnicodeValue", value);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(ByteString));
// Except: {"ab":"\u6587"}
Assert.AreEqual("7b226162223a225c7536353837227d", (item as ByteString).GetSpan().ToHexString());
}

[TestMethod]
public void TestUnicodeKeyValue()
{
_engine.Reset();
StackItem key = System.Text.Encoding.UTF8.GetBytes("中");
StackItem value = System.Text.Encoding.UTF8.GetBytes("文");
var result = _engine.ExecuteTestCaseStandard("testUnicodeKeyValue", key, value);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(ByteString));
// Except: {"\u4E2D":"\u6587"}
Assert.AreEqual("7b225c7534453244223a225c7536353837227d", (item as ByteString).GetSpan().ToHexString());
}

[TestMethod]
public void TestInt()
{
_engine.Reset();
StackItem key = 1;
_engine.ExecuteTestCaseStandard("testInt", key);
// Int cannot be used as the key for serializing Map
Assert.AreEqual(VMState.FAULT, _engine.State);
}

[TestMethod]
public void TestBool()
{
_engine.Reset();
StackItem key = true;
_engine.ExecuteTestCaseStandard("testBool", key);
// Bool cannot be used as the key for serializing Map
Assert.AreEqual(VMState.FAULT, _engine.State);
}

[TestMethod]
public void TestDeserialize()
{
_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testDeserialize", "a");
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Map));
var map = item as Map;
Assert.AreEqual(1, map.Count);
Assert.IsTrue(map.ContainsKey("a"));
Assert.AreEqual((ByteString)"testdeserialize", map["a"]);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ public void Init()
}

[TestMethod]
public void TestNext()
public void TestNextIntArray()
{
_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testNext", new Array(new StackItem[] { 1, 2, 3 }));
var result = _engine.ExecuteTestCaseStandard("testNextIntArray", new Array(new StackItem[] { 1, 2, 3 }));
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

Expand All @@ -32,12 +32,25 @@ public void TestNext()
}

[TestMethod]
public void TestConcat()
public void TestNextByteArray()
{
_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testNextByteArray", new byte[] { 1, 2, 3 });
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Integer));
Assert.AreEqual(6, item.GetInteger());
}

[TestMethod]
public void TestConcatIntArray()
{
// A and B

_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testConcat",
var result = _engine.ExecuteTestCaseStandard("testConcatIntArray",
new Array(new StackItem[] { 1, 2, 3 }),
new Array(new StackItem[] { 4, 5, 6 })
);
Expand All @@ -51,7 +64,7 @@ public void TestConcat()
// Only A

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcat",
result = _engine.ExecuteTestCaseStandard("testConcatIntArray",
new Array(new StackItem[] { 1, 2, 3 }),
new Array()
);
Expand All @@ -65,7 +78,7 @@ public void TestConcat()
// Only B

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcat",
result = _engine.ExecuteTestCaseStandard("testConcatIntArray",
new Array(),
new Array(new StackItem[] { 4, 5, 6 })
);
Expand All @@ -79,7 +92,7 @@ public void TestConcat()
// Empty

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcat",
result = _engine.ExecuteTestCaseStandard("testConcatIntArray",
new Array(),
new Array()
);
Expand All @@ -91,6 +104,66 @@ public void TestConcat()
Assert.AreEqual(0, item.GetSpan().Length);
}

[TestMethod]
public void TestConcatByteArray()
{
// A and B

_engine.Reset();
var result = _engine.ExecuteTestCaseStandard("testConcatByteArray",
new byte[] { 1, 2, 3 },
new byte[] { 4, 5, 6 }
);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

var item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Integer));
Assert.AreEqual(21, item.GetInteger());

// Only A

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcatByteArray",
new byte[] { 1, 2, 3 },
new byte[] { }
);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Integer));
Assert.AreEqual(6, item.GetInteger());

// Only B

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcatByteArray",
new byte[] { },
new byte[] { 4, 5, 6 }
);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Integer));
Assert.AreEqual(15, item.GetInteger());

// Empty

_engine.Reset();
result = _engine.ExecuteTestCaseStandard("testConcatByteArray",
new byte[] { },
new byte[] { }
);
Assert.AreEqual(VMState.HALT, _engine.State);
Assert.AreEqual(1, result.Count);

item = result.Pop();
Assert.IsInstanceOfType(item, typeof(Integer));
Assert.AreEqual(0, item.GetSpan().Length);
}

[TestMethod]
public void TestIntEnumerator()
{
Expand Down
Loading

0 comments on commit b143a7d

Please sign in to comment.