Skip to content

Commit bbe2a8f

Browse files
shargonJim8y
authored andcommitted
TestEngine: added Ownable and Oracle templates uts & fixes (neo-project#950)
* Ownable unit tests * Allow to export html and console joined coverage * Fix preview lang * fix html too * update workflow to generate artifacts * Clean format method selection * Export nef and manifest as static * Rename * replace typeof * clean csproj * Fix moq with transfer * Test oracle --------- Co-authored-by: Jimmy <[email protected]>
1 parent 696c8cd commit bbe2a8f

37 files changed

Lines changed: 714 additions & 327 deletions

File tree

.github/workflows/main.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,19 @@ jobs:
3131
run: |
3232
dotnet pack ./src/Neo.SmartContract.Template/Neo.SmartContract.Template.csproj
3333
dotnet new install ./src/Neo.SmartContract.Template/bin/Debug/Neo.SmartContract.Template.*.nupkg
34-
dotnet new neocontractnep17 -n Nep17Contract -o ./src/Neo.SmartContract.Template/bin/Debug/ --force
34+
dotnet new neocontractnep17 -n Nep17Contract -o ./src/Neo.SmartContract.Template/bin/Debug/nep17/ --force
35+
dotnet new neocontractowner -n Ownable -o ./src/Neo.SmartContract.Template/bin/Debug/ownable/ --force
36+
dotnet new neocontractoracle -n OracleRequest -o ./src/Neo.SmartContract.Template/bin/Debug/oracle/ --force
3537
dotnet new uninstall Neo.SmartContract.Template
36-
dotnet remove ./src/Neo.SmartContract.Template/bin/Debug/Nep17Contract.csproj package Neo.SmartContract.Framework
37-
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/Nep17Contract.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
38-
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/Nep17Contract.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Artifacts/ --generate-artifacts source --debug
38+
dotnet remove ./src/Neo.SmartContract.Template/bin/Debug/nep17/Nep17Contract.csproj package Neo.SmartContract.Framework
39+
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/nep17/Nep17Contract.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
40+
dotnet remove ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj package Neo.SmartContract.Framework
41+
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
42+
dotnet remove ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj package Neo.SmartContract.Framework
43+
dotnet add ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj reference ./src/Neo.SmartContract.Framework/Neo.SmartContract.Framework.csproj
44+
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/nep17/Nep17Contract.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractnep17/Artifacts/ --generate-artifacts source --debug
45+
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/ownable/Ownable.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractowner/Artifacts/ --generate-artifacts source --debug
46+
dotnet ./src/Neo.Compiler.CSharp/bin/Debug/net7.0/nccs.dll ./src/Neo.SmartContract.Template/bin/Debug/oracle/OracleRequest.csproj -o ./tests/Neo.SmartContract.Template.UnitTests/templates/neocontractoracle/Artifacts/ --generate-artifacts source --debug
3947
- name: Build Solution
4048
run: dotnet build ./neo-devpack-dotnet.sln
4149
- name: Add package coverlet.msbuild

src/Neo.Compiler.CSharp/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ private static int ProcessOutput(Options options, string folder, CompilationCont
212212

213213
if (options.GenerateArtifacts != Options.GenerateArtifactsKind.None)
214214
{
215-
var artifact = manifest.GetArtifactsSource(baseName);
215+
var artifact = manifest.GetArtifactsSource(baseName, nef, debugInfo);
216216

217217
if (options.GenerateArtifacts == Options.GenerateArtifactsKind.All || options.GenerateArtifacts == Options.GenerateArtifactsKind.Source)
218218
{

src/Neo.SmartContract.Template/templates/neocontractnep17/Nep17Contract.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using System.ComponentModel;
99
using System.Numerics;
1010

11-
namespace ProjectName
11+
namespace Neo.SmartContract.Template
1212
{
1313
[DisplayName(nameof(Nep17Contract))]
1414
[ManifestExtra("Author", "<Your Name Or Company Here>")]
@@ -109,7 +109,7 @@ public static void _deploy(object data, bool update)
109109
Storage.Put(Storage.CurrentContext, "Hello", "World");
110110
}
111111

112-
public static void Update(ByteString nefFile, string manifest, object data)
112+
public static void Update(ByteString nefFile, string manifest, object? data = null)
113113
{
114114
if (IsOwner() == false)
115115
throw new InvalidOperationException("No authorization.");

src/Neo.SmartContract.Template/templates/neocontractoracle/.template.config/template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"language": "C#",
1111
"type": "project"
1212
},
13-
"sourceName": "ProjectName",
13+
"sourceName": "OracleRequest",
1414
"symbols": {
1515
"NeoVersion": {
1616
"type": "parameter",

src/Neo.SmartContract.Template/templates/neocontractoracle/Contract1.cs renamed to src/Neo.SmartContract.Template/templates/neocontractoracle/OracleRequest.cs

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,26 @@
66
using Neo.SmartContract.Framework.Services;
77

88
using System;
9+
using System.Collections.Generic;
910
using System.ComponentModel;
1011

11-
namespace ProjectName
12+
namespace Neo.SmartContract.Template
1213
{
13-
[DisplayName(nameof(Contract1))]
14+
[DisplayName(nameof(OracleRequest))]
1415
[ManifestExtra("Author", "<Your Name Or Company Here>")]
1516
[ManifestExtra("Description", "<Description Here>")]
1617
[ManifestExtra("Email", "<Your Public Email Here>")]
1718
[ManifestExtra("Version", "<Version String Here>")]
18-
[ContractSourceCode("https://github.com/neo-project/neo-devpack-dotnet/tree/master/src/Neo.SmartContract.Template")]
19+
[ContractSourceCode("https://github.com/neo-project/neo-devpack-dotnet/tree/master/src/Neo.SmartContract.Template/templates/neocontractoracle/OracleRequest.cs")]
1920
[ContractPermission("*", "*")]
20-
public class Contract1 : SmartContract
21+
public class OracleRequest : Neo.SmartContract.Framework.SmartContract
2122
{
22-
public delegate void OnRequestSuccessfulDelegate(string requestedUrl, object jsonValue);
23-
24-
[DisplayName("RequestSuccessful")]
25-
public static event OnRequestSuccessfulDelegate OnRequestSuccessful;
26-
27-
// TODO: Replace it with your own address.
28-
[InitialValue("<Your Address Here>", ContractParameterType.Hash160)]
29-
static readonly UInt160 Owner = default;
30-
31-
private static bool IsOwner() => Runtime.CheckWitness(Owner);
32-
33-
// When this contract address is included in the transaction signature,
34-
// this method will be triggered as a VerificationTrigger to verify that the signature is correct.
35-
// For example, this method needs to be called when withdrawing token from the contract.
3623
[Safe]
37-
public static bool Verify() => IsOwner();
38-
39-
// TODO: Replace it with your methods.
40-
public static string MyMethod()
41-
{
42-
return Storage.Get(Storage.CurrentContext, "Hello");
43-
}
44-
45-
public static void _deploy(object data, bool update)
46-
{
47-
if (update)
48-
{
49-
// This will be executed during update
50-
return;
51-
}
52-
53-
// This will be executed during deploy
54-
Storage.Put(Storage.CurrentContext, "Hello", "World");
55-
}
56-
57-
public static void Update(ByteString nefFile, string manifest)
58-
{
59-
if (!IsOwner()) throw new Exception("No authorization.");
60-
ContractManagement.Update(nefFile, manifest, null);
61-
}
62-
63-
public static void Destroy()
24+
public static string GetResponse()
6425
{
65-
if (!IsOwner()) throw new Exception("No authorization.");
66-
ContractManagement.Destroy();
26+
return Storage.Get(Storage.CurrentContext, "Response");
6727
}
6828

69-
// TODO: Add your own logic
7029
public static void DoRequest()
7130
{
7231
/*
@@ -93,7 +52,7 @@ JSON DATA EXAMPLE
9352
}
9453

9554
// This method is called after the Oracle receives response from requested URL
96-
public static void OnOracleResponse(string requestedUrl, object userData, OracleResponseCode oracleResponse, string jsonString)
55+
public static void onOracleResponse(string requestedUrl, object userData, OracleResponseCode oracleResponse, string jsonString)
9756
{
9857
if (Runtime.CallingScriptHash != Oracle.Hash)
9958
throw new InvalidOperationException("No Authorization!");
@@ -103,7 +62,7 @@ public static void OnOracleResponse(string requestedUrl, object userData, Oracle
10362
var jsonArrayValues = (object[])StdLib.JsonDeserialize(jsonString);
10463
var jsonFirstValue = (string)jsonArrayValues[0];
10564

106-
OnRequestSuccessful(requestedUrl, jsonFirstValue);
65+
Storage.Put(Storage.CurrentContext, "Response", jsonFirstValue);
10766
}
10867
}
10968
}

src/Neo.SmartContract.Template/templates/neocontractoracle/ProjectName.csproj renamed to src/Neo.SmartContract.Template/templates/neocontractoracle/OracleRequest.csproj

File renamed without changes.

src/Neo.SmartContract.Template/templates/neocontractowner/.template.config/template.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"language": "C#",
1111
"type": "project"
1212
},
13-
"sourceName": "ProjectName",
13+
"sourceName": "Ownable",
1414
"symbols": {
1515
"NeoVersion": {
1616
"type": "parameter",

src/Neo.SmartContract.Template/templates/neocontractowner/Contract1.cs renamed to src/Neo.SmartContract.Template/templates/neocontractowner/Ownable.cs

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,56 @@
88
using System;
99
using System.ComponentModel;
1010

11-
namespace ProjectName
11+
namespace Neo.SmartContract.Template
1212
{
13-
[DisplayName(nameof(Contract1))]
13+
[DisplayName(nameof(Ownable))]
1414
[ManifestExtra("Author", "<Your Name Or Company Here>")]
1515
[ManifestExtra("Description", "<Description Here>")]
1616
[ManifestExtra("Email", "<Your Public Email Here>")]
1717
[ManifestExtra("Version", "<Version String Here>")]
18-
[ContractSourceCode("https://github.com/neo-project/neo-devpack-dotnet/tree/master/src/Neo.SmartContract.Template")]
18+
[ContractSourceCode("https://github.com/neo-project/neo-devpack-dotnet/tree/master/src/Neo.SmartContract.Template/templates/neocontractowner/Ownable.cs")]
1919
[ContractPermission("*", "*")]
20-
public class Contract1 : SmartContract
20+
public class Ownable : Neo.SmartContract.Framework.SmartContract
2121
{
22+
#region Owner
23+
2224
private const byte Prefix_Owner = 0xff;
2325

24-
public delegate void OnSetOwnerDelegate(UInt160 newOwner);
26+
[Safe]
27+
public static UInt160 GetOwner()
28+
{
29+
return (UInt160)Storage.Get(new[] { Prefix_Owner });
30+
}
31+
32+
private static bool IsOwner() =>
33+
Runtime.CheckWitness(GetOwner());
34+
35+
public delegate void OnSetOwnerDelegate(UInt160 previousOwner, UInt160 newOwner);
2536

2637
[DisplayName("SetOwner")]
2738
public static event OnSetOwnerDelegate OnSetOwner;
2839

29-
// TODO: Replace it with your own address.
30-
[InitialValue("<Your Address Here>", ContractParameterType.Hash160)]
31-
private static readonly UInt160 InitialOwner = default;
40+
public static void SetOwner(UInt160 newOwner)
41+
{
42+
if (IsOwner() == false)
43+
throw new InvalidOperationException("No Authorization!");
3244

33-
private static bool IsOwner() => Runtime.CheckWitness(GetOwner());
45+
ExecutionEngine.Assert(newOwner.IsValid && !newOwner.IsZero, "owner must be valid");
3446

35-
// When this contract address is included in the transaction signature,
36-
// this method will be triggered as a VerificationTrigger to verify that the signature is correct.
37-
// For example, this method needs to be called when withdrawing token from the contract.
38-
[Safe]
39-
public static bool Verify() => IsOwner();
47+
UInt160 previous = GetOwner();
48+
Storage.Put(new[] { Prefix_Owner }, newOwner);
49+
OnSetOwner(previous, newOwner);
50+
}
51+
52+
#endregion
4053

4154
// TODO: Replace it with your methods.
4255
public static string MyMethod()
4356
{
4457
return Storage.Get(Storage.CurrentContext, "Hello");
4558
}
4659

60+
// This will be executed during deploy
4761
public static void _deploy(object data, bool update)
4862
{
4963
if (update)
@@ -52,43 +66,30 @@ public static void _deploy(object data, bool update)
5266
return;
5367
}
5468

55-
// This will be executed during deploy
69+
// Init method, you must deploy the contract with the owner as an argument, or it will take the sender
70+
if (data is null) data = Runtime.Transaction.Sender;
71+
72+
UInt160 initialOwner = (UInt160)data;
73+
74+
ExecutionEngine.Assert(initialOwner.IsValid && !initialOwner.IsZero, "owner must exists");
75+
76+
Storage.Put(new[] { Prefix_Owner }, initialOwner);
77+
OnSetOwner(null, initialOwner);
5678
Storage.Put(Storage.CurrentContext, "Hello", "World");
5779
}
5880

59-
public static void Update(ByteString nefFile, string manifest)
81+
public static void Update(ByteString nefFile, string manifest, object? data = null)
6082
{
61-
if (!IsOwner()) throw new Exception("No authorization.");
62-
ContractManagement.Update(nefFile, manifest, null);
83+
if (IsOwner() == false)
84+
throw new InvalidOperationException("No authorization.");
85+
ContractManagement.Update(nefFile, manifest, data);
6386
}
6487

6588
public static void Destroy()
6689
{
67-
if (!IsOwner()) throw new Exception("No authorization.");
90+
if (!IsOwner())
91+
throw new InvalidOperationException("No authorization.");
6892
ContractManagement.Destroy();
6993
}
70-
71-
// Safe is for read operations Or Safe to call by everyone
72-
[Safe]
73-
public static UInt160 GetOwner()
74-
{
75-
var currentOwner = Storage.Get(new[] { Prefix_Owner });
76-
77-
if (currentOwner == null)
78-
return InitialOwner;
79-
80-
return (UInt160)currentOwner;
81-
}
82-
83-
public static void SetOwner(UInt160 newOwner)
84-
{
85-
if (IsOwner() == false)
86-
throw new InvalidOperationException("No Authorization!");
87-
if (newOwner != null && newOwner.IsValid)
88-
{
89-
Storage.Put(new[] { Prefix_Owner }, newOwner);
90-
OnSetOwner(newOwner);
91-
}
92-
}
9394
}
9495
}

src/Neo.SmartContract.Template/templates/neocontractowner/ProjectName.csproj renamed to src/Neo.SmartContract.Template/templates/neocontractowner/Ownable.csproj

File renamed without changes.

src/Neo.SmartContract.Testing/Coverage/CoverageBase.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ public IEnumerable<CoverageBranch> GetCoverageBranchFrom(int offset, int length)
9393
}
9494
}
9595

96+
/// <summary>
97+
/// Dump coverage
98+
/// </summary>
99+
/// <param name="format">Format</param>
100+
/// <returns>Coverage dump</returns>
101+
public abstract string Dump(DumpFormat format = DumpFormat.Console);
102+
96103
public static decimal CalculateHitRate(int total, int hits)
97104
=> total == 0 ? 1m : new decimal(hits) / new decimal(total);
98105

0 commit comments

Comments
 (0)