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

feat: adding support for arbitrary field #2717

Merged
merged 10 commits into from
Sep 11, 2024
45 changes: 26 additions & 19 deletions examples/gno.land/r/demo/profile/profile.gno
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package profile

import (
"errors"
"std"

"gno.land/p/demo/ufmt"
"gno.land/p/demo/avl"
"gno.land/p/demo/mux"
)
Expand Down Expand Up @@ -53,42 +53,49 @@ var boolFields = map[string]bool{

// Setters

func SetStringField(field, value string) error {
func SetStringField(field, value string) bool {
addr := std.PrevRealm().Addr()
if _, ok := stringFields[field]; !ok {
return errors.New("invalid string field")
key := addr.String() + ":" + field
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
updated := fields.Set(key, value)

event := "ProfileFieldCreated"
zivkovicmilos marked this conversation as resolved.
Show resolved Hide resolved
if updated {
event = "ProfileFieldUpdated"
}

key := addr.String() + ":" + field
fields.Set(key, value)
std.Emit(event, "type", "String", field, value)

return nil
return updated
}

func SetIntField(field string, value int) error {
func SetIntField(field string, value int) bool {
addr := std.PrevRealm().Addr()
key := addr.String() + ":" + field
updated := fields.Set(key, value)

if _, ok := intFields[field]; !ok {
return errors.New("invalid int field")
event := "ProfileFieldCreated"
if updated {
event = "ProfileFieldUpdated"
}

key := addr.String() + ":" + field
fields.Set(key, value)
std.Emit(event, "type", "Int", field, string(value))

return nil
return updated
}

func SetBoolField(field string, value bool) error {
func SetBoolField(field string, value bool) bool {
addr := std.PrevRealm().Addr()
key := addr.String() + ":" + field
updated := fields.Set(key, value)

if _, ok := boolFields[field]; !ok {
return errors.New("invalid bool field")
event := "ProfileFieldCreated"
if updated {
event = "ProfileFieldUpdated"
}

key := addr.String() + ":" + field
fields.Set(key, value)
std.Emit(event, "type", "Bool", field, ufmt.Sprintf("%t", value))

return nil
return updated
}

// Getters
Expand Down
96 changes: 61 additions & 35 deletions examples/gno.land/r/demo/profile/profile_test.gno
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package profile
import (
"std"
"testing"
"errors"

"gno.land/p/demo/testutils"
"gno.land/p/demo/uassert"
Expand All @@ -27,11 +28,15 @@ func TestStringFields(t *testing.T) {
name := GetStringField(alice, DisplayName, "anon")
uassert.Equal(t, "anon", name)

// Set
err := SetStringField(DisplayName, "Alice foo")
uassert.NoError(t, err)
err = SetStringField(Homepage, "https://example.com")
uassert.NoError(t, err)
// Set new key
updated := SetStringField(DisplayName, "Alice foo")
uassert.Equal(t, updated, false)
updated = SetStringField(Homepage, "https://example.com")
uassert.Equal(t, updated, false)

// Update the key
updated = SetStringField(DisplayName, "Alice foo")
uassert.Equal(t, updated, true)

// Get after setting
name = GetStringField(alice, DisplayName, "anon")
Expand All @@ -50,9 +55,13 @@ func TestIntFields(t *testing.T) {
age := GetIntField(bob, Age, 25)
uassert.Equal(t, 25, age)

// Set
err := SetIntField(Age, 30)
uassert.NoError(t, err)
// Set new key
updated := SetIntField(Age, 30)
uassert.Equal(t, updated, false)

// Update the key
updated = SetIntField(Age, 30)
uassert.Equal(t, updated, true)

// Get after setting
age = GetIntField(bob, Age, 25)
Expand All @@ -67,45 +76,28 @@ func TestBoolFields(t *testing.T) {
uassert.Equal(t, false, hiring)

// Set
err := SetBoolField(AvailableForHiring, true)
uassert.NoError(t, err)
updated := SetBoolField(AvailableForHiring, true)
uassert.Equal(t, updated, false)

// Update the key
updated = SetBoolField(AvailableForHiring, true)
uassert.Equal(t, updated, true)

// Get after setting
hiring = GetBoolField(charlie, AvailableForHiring, false)
uassert.Equal(t, true, hiring)
}

func TestInvalidStringField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(dave))

err := SetStringField(InvalidField, "test")
uassert.Error(t, err)
}

func TestInvalidIntField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(eve))

err := SetIntField(InvalidField, 123)
uassert.Error(t, err)
}

func TestInvalidBoolField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(frank))

err := SetBoolField(InvalidField, true)
uassert.Error(t, err)
}

func TestMultipleProfiles(t *testing.T) {
// Set profile for user1
std.TestSetRealm(std.NewUserRealm(user1))
err := SetStringField(DisplayName, "User One")
uassert.NoError(t, err)
updated := SetStringField(DisplayName, "User One")
uassert.Equal(t, updated, false)

// Set profile for user2
std.TestSetRealm(std.NewUserRealm(user2))
err = SetStringField(DisplayName, "User Two")
uassert.NoError(t, err)
updated = SetStringField(DisplayName, "User Two")
uassert.Equal(t, updated, false)

// Get profiles
std.TestSetRealm(std.NewUserRealm(user1)) // Switch back to user1
Expand All @@ -116,3 +108,37 @@ func TestMultipleProfiles(t *testing.T) {
uassert.Equal(t, "User One", name1)
uassert.Equal(t, "User Two", name2)
}

func TestArbitraryStringField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(user1))

// Set arbitrary string field
updated := SetStringField("MyEmail", "my@email.com")
uassert.Equal(t, updated, false)

val := GetStringField(user1, "MyEmail", "")
uassert.Equal(t, val, "my@email.com")
}

func TestArbitraryIntField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(user1))

// Set arbitrary int field
updated := SetIntField("MyIncome", 100_000)
uassert.Equal(t, updated, false)

val := GetIntField(user1, "MyIncome", 0)
uassert.Equal(t, val, 100_000)
}

func TestArbitraryBoolField(t *testing.T) {
std.TestSetRealm(std.NewUserRealm(user1))

// Set arbitrary int field
updated := SetBoolField("IsWinner", true)
uassert.Equal(t, updated, false)

val := GetBoolField(user1, "IsWinner", false)
uassert.Equal(t, val, true)
}

Loading