Skip to content

Commit

Permalink
Merge pull request #7 from simplitech/include-fake-storage-entries
Browse files Browse the repository at this point in the history
Include storage values in the TestEngine arguments
  • Loading branch information
melanke authored Oct 27, 2020
2 parents 3376c2f + ebbc6b4 commit 04d9c97
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 8 deletions.
18 changes: 18 additions & 0 deletions src/TestEngine/Engine.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using Neo.Cryptography.ECC;
using Neo.IO.Json;
using Neo.Ledger;
using Neo.Network.P2P.Payloads;
using Neo.SmartContract;
using Neo.SmartContract.Manifest;
using Neo.VM;
using Neo.VM.Types;
using System.Collections.Generic;

namespace Neo.TestingEngine
{
Expand Down Expand Up @@ -48,6 +50,22 @@ public void SetTestEngine(string path)
});
}

public void SetStorage(Dictionary<PrimitiveType, StackItem> storage)
{
foreach (var data in storage)
{
var key = new StorageKey()
{
Key = data.Key.GetSpan().ToArray()
};
var value = new StorageItem()
{
Value = data.Value.GetSpan().ToArray()
};
((TestDataCache<StorageKey, StorageItem>)engine.Snapshot.Storages).AddForTest(key, value);
}
}

public JObject Run(string method, StackItem[] args)
{
engine.GetMethod(method).RunEx(args);
Expand Down
63 changes: 55 additions & 8 deletions src/TestEngine/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ public static JObject RunWithMethodName(string path, string methodName, string j
}
}

return Run(path, methodName, parameters);
var smartContractTestCase = new SmartContractTest(path, methodName, parameters);
return Run(smartContractTestCase);
}
catch (Exception e)
{
Expand Down Expand Up @@ -126,7 +127,13 @@ public static JObject RunWithJson(JObject json)
var methodName = json["method"].AsString();
var parameters = (JArray)json["arguments"];

return Run(path, methodName, parameters);
var smartContractTestCase = new SmartContractTest(path, methodName, parameters);

if (json.ContainsProperty("storage"))
{
smartContractTestCase.storage = GetStorageFromJson(json["storage"]);
}
return Run(smartContractTestCase);
}
catch (Exception e)
{
Expand All @@ -141,29 +148,69 @@ public static JObject RunWithJson(JObject json)
/// <param name="method">The name of the targeted method</param>
/// <param name="parameters">Arguments of the method</param>
/// <returns>Returns a json with the engine state after executing the script</returns>
public static JObject Run(string path, string method, JArray parameters)
public static JObject Run(SmartContractTest smartContractTest)
{
if (!File.Exists(path))
if (!File.Exists(smartContractTest.nefPath))
{
return BuildJsonException("File doesn't exists");
}
if (Path.GetExtension(path).ToLowerInvariant() != ".nef")
if (Path.GetExtension(smartContractTest.nefPath).ToLowerInvariant() != ".nef")
{
return BuildJsonException("Invalid file. A .nef file required.");
}

try
{
Engine.Instance.SetTestEngine(path);
var stackParams = GetStackItemParameters(parameters);
return Engine.Instance.Run(method, stackParams);
Engine.Instance.SetTestEngine(smartContractTest.nefPath);

if (smartContractTest.storage.Count > 0)
{
Engine.Instance.SetStorage(smartContractTest.storage);
}

var stackParams = GetStackItemParameters(smartContractTest.methodParameters);
return Engine.Instance.Run(smartContractTest.methodName, stackParams);
}
catch (Exception e)
{
return BuildJsonException(e.Message);
}
}

/// <summary>
/// Converts the data in a json array to a dictionary of StackItem
/// </summary>
/// <param name="jsonStorage">json array with the map values to be converted</param>
/// <returns>Returns the built StackItem dictionary</returns>
private static Dictionary<PrimitiveType, StackItem> GetStorageFromJson(JObject jsonStorage)
{
if (!(jsonStorage is JArray storage))
{
throw new Exception("Expecting an array object in 'storage'");
}

var missingFieldMessage = "Missing field '{0}'";
var items = new Dictionary<PrimitiveType, StackItem>();
foreach (var pair in storage)
{
if (!pair.ContainsProperty("key"))
{
throw new Exception(string.Format(missingFieldMessage, "key"));
}

if (!pair.ContainsProperty("value"))
{
throw new Exception(string.Format(missingFieldMessage, "value"));
}

var key = (PrimitiveType)ContractParameter.FromJson(pair["key"]).ToStackItem();
var value = ContractParameter.FromJson(pair["value"]).ToStackItem();
items[key] = value;
}

return items;
}

/// <summary>
/// Converts the data in a json array to an array of StackItem
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions src/TestEngine/SmartContractTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Neo.IO.Json;
using Neo.VM.Types;
using System.Collections.Generic;

namespace Neo.TestingEngine
{
public class SmartContractTest
{
public string nefPath;
public string methodName;
public JArray methodParameters;
public Dictionary<PrimitiveType, StackItem> storage = new Dictionary<PrimitiveType, StackItem>();

public SmartContractTest(string path, string method, JArray parameters)
{
nefPath = path;
methodName = method;
methodParameters = parameters;
storage.Clear();
}
}
}
8 changes: 8 additions & 0 deletions src/TestEngine/TestUtils/TestDataCache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,13 @@ public void Clear()
{
dic.Clear();
}

/// <summary>
/// Include a new value to the storage for unit test
/// </summary>
public void AddForTest(TKey key, TValue value)
{
AddInternal(key, value);
}
}
}
43 changes: 43 additions & 0 deletions tests/TestEngine.UnitTests/UnitTest_Invoke.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Neo.TestingEngine;
using Neo.VM;
using Neo.VM.Types;
using System.Collections.Generic;
using System.IO;
using Compiler = Neo.Compiler.Program;

Expand Down Expand Up @@ -271,5 +272,47 @@ public void Test_Json_With_Parameters()
Assert.IsTrue(resultStack[0].ContainsProperty("value"));
Assert.AreEqual(resultStack[0]["value"].AsString(), wantresult.ToJson()["value"].AsString());
}

[TestMethod]
public void Test_Json_With_Storage()
{
StackItem arguments = 16;
PrimitiveType key = "example";
StackItem value = 123;

Map storage = new Map()
{
[key] = value
};

var json = new JObject();
json["path"] = "./TestClasses/Contract1.nef";
json["method"] = "testArgs1";
json["arguments"] = new JArray() { arguments.ToParameter().ToJson() };
json["storage"] = storage.ToParameter().ToJson()["value"];

var args = new string[] {
json.AsString()
};
var result = Program.Run(args);

// search in the storage
Assert.IsTrue(result.ContainsProperty("storage"));
Assert.IsInstanceOfType(result["storage"], typeof(JArray));

storage[key] = value.GetSpan().ToArray();
var storageArray = result["storage"] as JArray;

var contains = false;
foreach (var pair in storageArray)
{
if (pair.AsString() == storage.ToJson()["value"].AsString())
{
contains = true;
break;
}
}
Assert.IsTrue(contains);
}
}
}

0 comments on commit 04d9c97

Please sign in to comment.