Skip to content

Commit 8b33bc7

Browse files
update testutils to use JSON outputs for contract publishing
1 parent 7143812 commit 8b33bc7

File tree

1 file changed

+68
-18
lines changed

1 file changed

+68
-18
lines changed

relayer/testutils/contract.go

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ import (
55
"bytes"
66
"encoding/base64"
77
"encoding/json"
8-
"errors"
98
"fmt"
109
"log"
1110
"os"
1211
"os/exec"
1312
"path/filepath"
14-
"regexp"
1513
"runtime"
1614
"strconv"
15+
"strings"
1716
"testing"
1817

1918
"github.com/pelletier/go-toml/v2"
@@ -28,12 +27,18 @@ type ObjectChange struct {
2827
Sender string `json:"sender,omitempty"`
2928
Owner Owner `json:"owner,omitempty"`
3029
ObjectType string `json:"objectType,omitempty"`
30+
ObjectTypeSnake string `json:"object_type,omitempty"`
3131
ObjectID string `json:"objectId,omitempty"`
32+
ObjectIDSnake string `json:"object_id,omitempty"`
3233
Version string `json:"version,omitempty"`
3334
PreviousVersion string `json:"previousVersion,omitempty"`
3435
Digest string `json:"digest,omitempty"`
3536
PackageID string `json:"packageId,omitempty"` // Only in type == "published"
36-
Modules []string `json:"modules,omitempty"` // Only in type == "published"
37+
OutputState string `json:"outputState,omitempty"`
38+
OutputStateAlt string `json:"output_state,omitempty"`
39+
IDOperation string `json:"idOperation,omitempty"`
40+
IDOperationAlt string `json:"id_operation,omitempty"`
41+
Modules []string `json:"modules,omitempty"` // Only in type == "published"
3742
}
3843

3944
type Owner struct {
@@ -47,7 +52,40 @@ type SharedOwner struct {
4752
}
4853

4954
type TxnMetaWithObjectChanges struct {
50-
ObjectChanges []ObjectChange `json:"objectChanges"`
55+
ObjectChanges []ObjectChange `json:"objectChanges"`
56+
ObjectChangesSnake []ObjectChange `json:"object_changes"`
57+
ChangedObjects []ObjectChange `json:"changed_objects"`
58+
ChangedObjectsCamel []ObjectChange `json:"changedObjects"`
59+
}
60+
61+
func normalizeObjectChanges(changes []ObjectChange) []ObjectChange {
62+
for i := range changes {
63+
if changes[i].ObjectID == "" {
64+
changes[i].ObjectID = changes[i].ObjectIDSnake
65+
}
66+
if changes[i].ObjectType == "" {
67+
changes[i].ObjectType = changes[i].ObjectTypeSnake
68+
}
69+
if changes[i].OutputState == "" {
70+
changes[i].OutputState = changes[i].OutputStateAlt
71+
}
72+
if changes[i].IDOperation == "" {
73+
changes[i].IDOperation = changes[i].IDOperationAlt
74+
}
75+
76+
// Newer Sui JSON uses object-level metadata rather than "type":"published/created".
77+
if changes[i].Type == "" {
78+
if changes[i].ObjectType == "package" || changes[i].OutputState == "OUTPUT_OBJECT_STATE_PACKAGE_WRITE" {
79+
changes[i].Type = "published"
80+
if changes[i].PackageID == "" {
81+
changes[i].PackageID = changes[i].ObjectID
82+
}
83+
} else if strings.EqualFold(changes[i].IDOperation, "CREATED") {
84+
changes[i].Type = "created"
85+
}
86+
}
87+
}
88+
return changes
5189
}
5290

5391
func BuildSetup(t *testing.T, packagePath string) string {
@@ -69,14 +107,13 @@ func BuildSetup(t *testing.T, packagePath string) string {
69107
return contractPath
70108
}
71109

72-
func findDigestIndex(input string) (int, error) {
73-
digestRegex := regexp.MustCompile(`"digest":\s*"[A-Za-z0-9]+"`)
74-
loc := digestRegex.FindStringIndex(input)
75-
if loc == nil {
76-
return -1, errors.New("digest not found")
110+
func extractJSONOutput(output string) (string, error) {
111+
start := strings.Index(output, "{")
112+
end := strings.LastIndex(output, "}")
113+
if start == -1 || end == -1 || end < start {
114+
return "", fmt.Errorf("json output not found")
77115
}
78-
79-
return loc[0], nil
116+
return output[start : end+1], nil
80117
}
81118

82119
func BuildContract(t *testing.T, contractPath string) {
@@ -172,26 +209,39 @@ func PublishContract(t *testing.T, packageName string, contractPath string, acco
172209
publishOutput, err := publishCmd.CombinedOutput()
173210
require.NoError(t, err, "Failed to publish contract: %s", string(publishOutput))
174211

175-
// This is a hack to skip the warnings from the CLI output by searching for "digest" with regex
176-
// and then extracting the JSON from there.
177-
idx, err := findDigestIndex(string(publishOutput))
212+
cleanedOutput, err := extractJSONOutput(string(publishOutput))
178213
require.NoError(t, err)
179-
cleanedOutput := "{" + string(publishOutput)[idx:]
180214

181215
// Unmarshal the JSON into a map.
182216
var parsedPublishTxn TxnMetaWithObjectChanges
183-
if err := json.Unmarshal([]byte(cleanedOutput), &parsedPublishTxn); err != nil {
184-
log.Fatalf("failed to unmarshal JSON: %v", err)
217+
err = json.Unmarshal([]byte(cleanedOutput), &parsedPublishTxn)
218+
require.NoError(t, err, "Failed to parse publish output: %s", cleanedOutput)
219+
220+
if len(parsedPublishTxn.ObjectChanges) == 0 && len(parsedPublishTxn.ObjectChangesSnake) > 0 {
221+
parsedPublishTxn.ObjectChanges = parsedPublishTxn.ObjectChangesSnake
222+
}
223+
if len(parsedPublishTxn.ObjectChanges) == 0 && len(parsedPublishTxn.ChangedObjects) > 0 {
224+
parsedPublishTxn.ObjectChanges = parsedPublishTxn.ChangedObjects
185225
}
226+
if len(parsedPublishTxn.ObjectChanges) == 0 && len(parsedPublishTxn.ChangedObjectsCamel) > 0 {
227+
parsedPublishTxn.ObjectChanges = parsedPublishTxn.ChangedObjectsCamel
228+
}
229+
parsedPublishTxn.ObjectChanges = normalizeObjectChanges(parsedPublishTxn.ObjectChanges)
186230

187231
changes := parsedPublishTxn.ObjectChanges
188232

189233
var packageId string
190234
for _, change := range changes {
191-
if change.Type == "published" {
235+
if change.Type == "published" && change.PackageID != "" {
192236
packageId = change.PackageID
193237
break
194238
}
239+
240+
// Newer Sui output can represent package publish as objectType=package.
241+
if (change.ObjectType == "package" || change.OutputState == "OUTPUT_OBJECT_STATE_PACKAGE_WRITE") && change.ObjectID != "" {
242+
packageId = change.ObjectID
243+
break
244+
}
195245
}
196246
require.NotEmpty(t, packageId, "Package ID not found")
197247

0 commit comments

Comments
 (0)