Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add byte.AsString and Map UTs #303

Merged
merged 18 commits into from
Jul 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
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