Skip to content

Commit

Permalink
Improve code coverage (#3354)
Browse files Browse the repository at this point in the history
* update

* remove binary file

* Add UT and fixed bug

* Add UT and fixed bug

* Add UT

* Add UT

* Add UT

* Update src/Neo/SmartContract/Manifest/ContractManifest.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

* Update src/Neo/SmartContract/Manifest/ContractManifest.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

* Update src/Neo/SmartContract/Manifest/ContractManifest.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

* Update Base58.cs

* Update UT_Cryptography_Helper.cs

* Update Base58.cs

* update

* Update ContractManifest.cs

* Revert change that affect a syscall

* Revert try

* Remove using

* Update src/Neo/SmartContract/Manifest/ContractManifest.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

* Update src/Neo/SmartContract/Manifest/ContractAbi.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

* Update src/Neo/SmartContract/Manifest/ContractManifest.cs

Co-authored-by: Christopher Schuchardt <[email protected]>

---------

Co-authored-by: Christopher Schuchardt <[email protected]>
Co-authored-by: Jimmy <[email protected]>
Co-authored-by: Fernando Diaz Toledano <[email protected]>
Co-authored-by: NGD Admin <[email protected]>
  • Loading branch information
5 people committed Jul 11, 2024
1 parent 97e24ed commit bfb3440
Show file tree
Hide file tree
Showing 19 changed files with 261 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/Neo/SmartContract/Manifest/ContractAbi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ public static ContractAbi FromJson(JObject json)
{
ContractAbi abi = new()
{
Methods = ((JArray)json["methods"]).Select(u => ContractMethodDescriptor.FromJson((JObject)u)).ToArray(),
Events = ((JArray)json["events"]).Select(u => ContractEventDescriptor.FromJson((JObject)u)).ToArray()
Methods = ((JArray)json!["methods"])?.Select(u => ContractMethodDescriptor.FromJson((JObject)u)).ToArray() ?? [],
Events = ((JArray)json!["events"])?.Select(u => ContractEventDescriptor.FromJson((JObject)u)).ToArray() ?? []
};
if (abi.Methods.Length == 0) throw new FormatException();
return abi;
Expand Down
11 changes: 6 additions & 5 deletions src/Neo/SmartContract/Manifest/ContractManifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,20 +112,21 @@ public static ContractManifest FromJson(JObject json)
{
ContractManifest manifest = new()
{
Name = json["name"].GetString(),
Groups = ((JArray)json["groups"]).Select(u => ContractGroup.FromJson((JObject)u)).ToArray(),
SupportedStandards = ((JArray)json["supportedstandards"]).Select(u => u.GetString()).ToArray(),
Name = json["name"]!.GetString(),
Groups = ((JArray)json["groups"])?.Select(u => ContractGroup.FromJson((JObject)u)).ToArray() ?? [],
SupportedStandards = ((JArray)json["supportedstandards"])?.Select(u => u.GetString()).ToArray() ?? [],
Abi = ContractAbi.FromJson((JObject)json["abi"]),
Permissions = ((JArray)json["permissions"]).Select(u => ContractPermission.FromJson((JObject)u)).ToArray(),
Permissions = ((JArray)json["permissions"])?.Select(u => ContractPermission.FromJson((JObject)u)).ToArray() ?? [],
Trusts = WildcardContainer<ContractPermissionDescriptor>.FromJson(json["trusts"], u => ContractPermissionDescriptor.FromJson((JString)u)),
Extra = (JObject)json["extra"]
};

if (string.IsNullOrEmpty(manifest.Name))
throw new FormatException();
_ = manifest.Groups.ToDictionary(p => p.PubKey);
if (json["features"] is not JObject features || features.Count != 0)
throw new FormatException();
if (manifest.SupportedStandards.Any(p => string.IsNullOrEmpty(p)))
if (manifest.SupportedStandards.Any(string.IsNullOrEmpty))
throw new FormatException();
_ = manifest.SupportedStandards.ToDictionary(p => p);
_ = manifest.Permissions.ToDictionary(p => p.Contract);
Expand Down
13 changes: 13 additions & 0 deletions tests/Neo.Json.UnitTests/UT_JArray.cs
Original file line number Diff line number Diff line change
Expand Up @@ -254,5 +254,18 @@ public void TestAsString()
var s = jArray.AsString();
Assert.AreEqual(s, "{\"name\":\"alice\",\"age\":30,\"score\":100.001,\"gender\":\"female\",\"isMarried\":true,\"pet\":{\"name\":\"Tom\",\"type\":\"cat\"}},{\"name\":\"bob\",\"age\":100000,\"score\":0.001,\"gender\":\"male\",\"isMarried\":false,\"pet\":{\"name\":\"Paul\",\"type\":\"dog\"}}");
}

[TestMethod]
public void TestClone()
{
var jArray = new JArray
{
alice,
bob,
};
var a = jArray.AsString();
var b = jArray.Clone().AsString();
a.Should().Be(b);
}
}
}
2 changes: 2 additions & 0 deletions tests/Neo.Json.UnitTests/UT_JBoolean.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ public void TestEqual()
{
Assert.IsTrue(jTrue.Equals(new JBoolean(true)));
Assert.IsTrue(jTrue == new JBoolean(true));
Assert.IsTrue(jTrue != new JBoolean(false));
Assert.IsTrue(jFalse.Equals(new JBoolean()));
Assert.IsTrue(jFalse == new JBoolean());
Assert.IsTrue(jFalse.GetBoolean().ToString().ToLowerInvariant() == jFalse.ToString());
}
}
}
23 changes: 23 additions & 0 deletions tests/Neo.Json.UnitTests/UT_JNumber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using System.Numerics;

namespace Neo.Json.UnitTests
{
enum Woo
Expand Down Expand Up @@ -72,6 +74,27 @@ public void TestEqual()
Assert.IsTrue(minInt.Equals(JNumber.MIN_SAFE_INTEGER));
Assert.IsTrue(minInt == JNumber.MIN_SAFE_INTEGER);
Assert.IsTrue(zero == new JNumber());
Assert.IsFalse(zero != new JNumber());
Assert.IsTrue(zero.AsNumber() == zero.GetNumber());
Assert.IsFalse(zero == null);

var jnum = new JNumber(1);
jnum.Equals(new JNumber(1)).Should().BeTrue();
jnum.Equals((uint)1).Should().BeTrue();
jnum.Equals((int)1).Should().BeTrue();
jnum.Equals((ulong)1).Should().BeTrue();
jnum.Equals((long)1).Should().BeTrue();
jnum.Equals((byte)1).Should().BeTrue();
jnum.Equals((sbyte)1).Should().BeTrue();
jnum.Equals((short)1).Should().BeTrue();
jnum.Equals((ushort)1).Should().BeTrue();
jnum.Equals((decimal)1).Should().BeTrue();
jnum.Equals((float)1).Should().BeTrue();
jnum.Equals((double)1).Should().BeTrue();
jnum.Equals(null).Should().BeFalse();
var x = jnum;
jnum.Equals(x).Should().BeTrue();
Assert.ThrowsException<ArgumentOutOfRangeException>(() => jnum.Equals(new BigInteger(1)));
}
}
}
16 changes: 14 additions & 2 deletions tests/Neo.Json.UnitTests/UT_JString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,22 @@ public void TestGetEnum()
public void TestEqual()
{
var str = "hello world";
var str2 = "hello world2";
var jString = new JString(str);
Assert.IsTrue(jString.Equals(str));
var jString2 = new JString(str2);

Assert.IsTrue(jString == str);
Assert.IsTrue(jString != "hello world2");
Assert.IsFalse(jString == null);
Assert.IsTrue(jString != str2);
Assert.IsFalse(jString == str2);

Assert.AreEqual(str, jString.GetString());
Assert.IsTrue(jString.Equals(str));
Assert.IsFalse(jString.Equals(jString2));
Assert.IsFalse(jString.Equals(null));
Assert.IsFalse(jString.Equals(123));
var reference = jString;
Assert.IsTrue(jString.Equals(reference));
}
}
}
2 changes: 2 additions & 0 deletions tests/Neo.UnitTests/Cryptography/UT_BloomFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public void TestBloomFIlterConstructorGetKMTweak()
uint nTweak = 123456;
Action action = () => new BloomFilter(m, n, nTweak);
action.Should().Throw<ArgumentOutOfRangeException>();
action = () => new BloomFilter(m, n, nTweak, new byte[] { 0, 1, 2, 3, 4 });
action.Should().Throw<ArgumentOutOfRangeException>();

m = 7;
n = -10;
Expand Down
24 changes: 24 additions & 0 deletions tests/Neo.UnitTests/Cryptography/UT_Cryptography_Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ public void TestBase58CheckDecode()
input = "3vQB7B6MrGQZaxCuFg4og";
action = () => input.Base58CheckDecode();
action.Should().Throw<FormatException>();

Assert.ThrowsException<FormatException>(() => string.Empty.Base58CheckDecode());
}

[TestMethod]
public void TestMurmurReadOnlySpan()
{
ReadOnlySpan<byte> input = "Hello, world!"u8;
byte[] input2 = input.ToArray();
input.Murmur32(0).Should().Be(input2.Murmur32(0));
input.Murmur128(0).Should().Equal(input2.Murmur128(0));
}

[TestMethod]
Expand All @@ -50,6 +61,19 @@ public void TestSha256()
byte[] result = value.Sha256(0, value.Length);
string resultStr = result.ToHexString();
resultStr.Should().Be("b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9");
value.Sha256().Should().Equal(result);
((Span<byte>)value).Sha256().Should().Equal(result);
((ReadOnlySpan<byte>)value).Sha256().Should().Equal(result);
}

[TestMethod]
public void TestKeccak256()
{
var input = "Hello, world!"u8.ToArray();
var result = input.Keccak256();
result.ToHexString().Should().Be("b6e16d27ac5ab427a7f68900ac5559ce272dc6c37c82b3e052246c82244c50e4");
((Span<byte>)input).Keccak256().Should().Equal(result);
((ReadOnlySpan<byte>)input).Keccak256().Should().Equal(result);
}

[TestMethod]
Expand Down
3 changes: 3 additions & 0 deletions tests/Neo.UnitTests/Neo.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
</ItemGroup>

<ItemGroup>
<None Update="SmartContract\Manifest\TestFile\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="test.config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
Expand Down
21 changes: 21 additions & 0 deletions tests/Neo.UnitTests/Network/P2P/Payloads/UT_Block.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,26 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.IO;
using Neo.Json;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
using Neo.SmartContract.Native;

namespace Neo.UnitTests.Network.P2P.Payloads
{
[TestClass]
public class UT_Block
{
Block uut;
private static ApplicationEngine GetEngine(bool hasContainer = false, bool hasSnapshot = false, bool hasBlock = false, bool addScript = true, long gas = 20_00000000)
{
var tx = hasContainer ? TestUtils.GetTransaction(UInt160.Zero) : null;
var snapshot = hasSnapshot ? TestBlockchain.GetTestSnapshot() : null;
var block = hasBlock ? new Block { Header = new Header() } : null;
var engine = ApplicationEngine.Create(TriggerType.Application, tx, snapshot, block, TestBlockchain.TheNeoSystem.Settings, gas: gas);
if (addScript) engine.LoadScript(new byte[] { 0x01 });
return engine;
}

[TestInitialize]
public void TestSetup()
Expand Down Expand Up @@ -136,6 +148,15 @@ private void AssertStandardBlockTestVals(UInt256 val256, UInt256 merkRoot, UInt1
public void Equals_SameObj()
{
uut.Equals(uut).Should().BeTrue();
var obj = uut as object;
uut.Equals(obj).Should().BeTrue();
}

[TestMethod]
public void TestGetHashCode()
{
var snapshot = GetEngine(true, true).Snapshot;
NativeContract.Ledger.GetBlock(snapshot, 0).GetHashCode().Should().Be(-626492395);
}

[TestMethod]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleContractCall","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"onNEP17Payment","parameters":[{"name":"from","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Integer"}],"returntype":"Void","offset":0,"safe":false},{"name":"_initialize","parameters":[],"returntype":"Void","offset":91,"safe":false}],"events":[]},"permissions":[],"trusts":[],"extra":{"Author":"core-dev","Version":"0.0.1","Description":"A sample contract to demonstrate how to call a contract","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleEvent","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"main","parameters":[],"returntype":"Boolean","offset":0,"safe":false}],"events":[{"name":"new_event_name","parameters":[{"name":"arg1","type":"ByteArray"},{"name":"arg2","type":"String"},{"name":"arg3","type":"Integer"}]},{"name":"event2","parameters":[{"name":"arg1","type":"ByteArray"},{"name":"arg2","type":"Integer"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":{"Author":"code-dev","Description":"A sample contract that demonstrates how to use Events","Version":"0.0.1","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleException","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"try01","parameters":[],"returntype":"Any","offset":0,"safe":false},{"name":"try02","parameters":[],"returntype":"Any","offset":77,"safe":false},{"name":"try03","parameters":[],"returntype":"Any","offset":166,"safe":false},{"name":"tryNest","parameters":[],"returntype":"Any","offset":259,"safe":false},{"name":"tryFinally","parameters":[],"returntype":"Any","offset":404,"safe":false},{"name":"tryFinallyAndRethrow","parameters":[],"returntype":"Any","offset":474,"safe":false},{"name":"tryCatch","parameters":[],"returntype":"Any","offset":550,"safe":false},{"name":"tryWithTwoFinally","parameters":[],"returntype":"Any","offset":628,"safe":false},{"name":"tryecpointCast","parameters":[],"returntype":"Any","offset":920,"safe":false},{"name":"tryvalidByteString2Ecpoint","parameters":[],"returntype":"Any","offset":1010,"safe":false},{"name":"tryinvalidByteArray2UInt160","parameters":[],"returntype":"Any","offset":1100,"safe":false},{"name":"tryvalidByteArray2UInt160","parameters":[],"returntype":"Any","offset":1190,"safe":false},{"name":"tryinvalidByteArray2UInt256","parameters":[],"returntype":"Any","offset":1280,"safe":false},{"name":"tryvalidByteArray2UInt256","parameters":[],"returntype":"Any","offset":1370,"safe":false},{"name":"tryNULL2Ecpoint_1","parameters":[],"returntype":"Array","offset":1476,"safe":false},{"name":"tryNULL2Uint160_1","parameters":[],"returntype":"Array","offset":1652,"safe":false},{"name":"tryNULL2Uint256_1","parameters":[],"returntype":"Array","offset":1828,"safe":false},{"name":"tryNULL2Bytestring_1","parameters":[],"returntype":"Array","offset":1990,"safe":false},{"name":"tryUncatchableException","parameters":[],"returntype":"Any","offset":2141,"safe":false},{"name":"_initialize","parameters":[],"returntype":"Void","offset":2219,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":{"Author":"core-dev","Description":"A sample contract to demonstrate how to handle exception","Version":"0.0.1","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleHelloWorld","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"sayHello","parameters":[],"returntype":"String","offset":0,"safe":true}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":{"Description":"A simple \u0060hello world\u0060 contract","E-mail":"[email protected]","Version":"0.0.1","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleNep17Token","groups":[],"features":{},"supportedstandards":["NEP-17"],"abi":{"methods":[{"name":"symbol","parameters":[],"returntype":"String","offset":1333,"safe":true},{"name":"decimals","parameters":[],"returntype":"Integer","offset":1348,"safe":true},{"name":"totalSupply","parameters":[],"returntype":"Integer","offset":52,"safe":true},{"name":"balanceOf","parameters":[{"name":"owner","type":"Hash160"}],"returntype":"Integer","offset":98,"safe":true},{"name":"transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"},{"name":"data","type":"Any"}],"returntype":"Boolean","offset":362,"safe":false},{"name":"getOwner","parameters":[],"returntype":"Hash160","offset":808,"safe":true},{"name":"setOwner","parameters":[{"name":"newOwner","type":"Any"}],"returntype":"Void","offset":877,"safe":false},{"name":"getMinter","parameters":[],"returntype":"Hash160","offset":980,"safe":true},{"name":"setMinter","parameters":[{"name":"newMinter","type":"Hash160"}],"returntype":"Void","offset":1025,"safe":false},{"name":"mint","parameters":[{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Void","offset":1103,"safe":false},{"name":"burn","parameters":[{"name":"account","type":"Hash160"},{"name":"amount","type":"Integer"}],"returntype":"Void","offset":1158,"safe":false},{"name":"verify","parameters":[],"returntype":"Boolean","offset":1216,"safe":true},{"name":"update","parameters":[{"name":"nefFile","type":"ByteArray"},{"name":"manifest","type":"String"}],"returntype":"Boolean","offset":1222,"safe":false},{"name":"_initialize","parameters":[],"returntype":"Void","offset":1271,"safe":false}],"events":[{"name":"Transfer","parameters":[{"name":"from","type":"Hash160"},{"name":"to","type":"Hash160"},{"name":"amount","type":"Integer"}]},{"name":"SetOwner","parameters":[{"name":"newOwner","type":"Hash160"}]},{"name":"SetMinter","parameters":[{"name":"newMinter","type":"Hash160"}]}]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":{"Author":"core-dev","Version":"0.0.1","Description":"A sample NEP-17 token","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"name":"SampleOracle","groups":[],"features":{},"supportedstandards":[],"abi":{"methods":[{"name":"getResponse","parameters":[],"returntype":"String","offset":0,"safe":true},{"name":"doRequest","parameters":[],"returntype":"Void","offset":35,"safe":false},{"name":"onOracleResponse","parameters":[{"name":"requestedUrl","type":"String"},{"name":"userData","type":"Any"},{"name":"oracleResponse","type":"Integer"},{"name":"jsonString","type":"String"}],"returntype":"Void","offset":333,"safe":false}],"events":[]},"permissions":[{"contract":"*","methods":"*"}],"trusts":[],"extra":{"Author":"code-dev","Description":"A sample contract to demonstrate how to use Example.SmartContract.Oracle Service","Version":"0.0.1","Sourcecode":"https://github.com/neo-project/neo-devpack-dotnet/tree/master/examples/"}}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.Json;
using Neo.SmartContract.Manifest;
using Neo.SmartContract.Native;
using Neo.Wallets;
using System;
using System.Security.Cryptography;

namespace Neo.UnitTests.SmartContract.Manifest
Expand All @@ -34,7 +37,7 @@ public void TestCreateByECPointAndIsWildcard()
}

[TestMethod]
public void TestFromAndToJson()
public void TestContractPermissionDescriptorFromAndToJson()
{
byte[] privateKey = new byte[32];
RandomNumberGenerator rng = RandomNumberGenerator.Create();
Expand All @@ -44,6 +47,20 @@ public void TestFromAndToJson()
ContractPermissionDescriptor result = ContractPermissionDescriptor.FromJson(temp.ToJson());
Assert.AreEqual(null, result.Hash);
Assert.AreEqual(result.Group, result.Group);
Assert.ThrowsException<FormatException>(() => ContractPermissionDescriptor.FromJson(string.Empty));
}

[TestMethod]
public void TestContractManifestFromJson()
{
Assert.ThrowsException<NullReferenceException>(() => ContractManifest.FromJson(new Json.JObject()));
var jsonFiles = System.IO.Directory.GetFiles(System.IO.Path.Combine("SmartContract", "Manifest", "TestFile"));
foreach (var item in jsonFiles)
{
var json = JObject.Parse(System.IO.File.ReadAllText(item)) as JObject;
var manifest = ContractManifest.FromJson(json);
manifest.ToJson().ToString().Should().Be(json.ToString());
}
}

[TestMethod]
Expand Down
4 changes: 4 additions & 0 deletions tests/Neo.UnitTests/SmartContract/Native/UT_StdLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// Redistribution and use in source and binary forms with or without
// modifications are permitted.

using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Neo.SmartContract;
using Neo.SmartContract.Native;
Expand Down Expand Up @@ -53,6 +54,9 @@ public void TestItoaAtoi()
Assert.ThrowsException<System.FormatException>(() => StdLib.Atoi("a", 10));
Assert.ThrowsException<System.FormatException>(() => StdLib.Atoi("g", 16));
Assert.ThrowsException<System.ArgumentOutOfRangeException>(() => StdLib.Atoi("a", 11));

StdLib.Atoi(StdLib.Itoa(BigInteger.One, 10)).Should().Be(BigInteger.One);
StdLib.Atoi(StdLib.Itoa(BigInteger.MinusOne, 10)).Should().Be(BigInteger.MinusOne);
}

[TestMethod]
Expand Down
Loading

0 comments on commit bfb3440

Please sign in to comment.