github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/examples/gno.land/p/demo/json/encode_test.gno (about)

     1  package json
     2  
     3  import (
     4  	"testing"
     5  )
     6  
     7  func TestMarshal_Primitive(t *testing.T) {
     8  	tests := []struct {
     9  		name string
    10  		node *Node
    11  	}{
    12  		{
    13  			name: "null",
    14  			node: NullNode(""),
    15  		},
    16  		{
    17  			name: "true",
    18  			node: BoolNode("", true),
    19  		},
    20  		{
    21  			name: "false",
    22  			node: BoolNode("", false),
    23  		},
    24  		{
    25  			name: `"string"`,
    26  			node: StringNode("", "string"),
    27  		},
    28  		{
    29  			name: `"one \"encoded\" string"`,
    30  			node: StringNode("", `one "encoded" string`),
    31  		},
    32  		{
    33  			name: `{"foo":"bar"}`,
    34  			node: ObjectNode("", map[string]*Node{
    35  				"foo": StringNode("foo", "bar"),
    36  			}),
    37  		},
    38  		{
    39  			name: "42",
    40  			node: NumberNode("", 42),
    41  		},
    42  		// TODO: fix output for not to use scientific notation
    43  		{
    44  			name: "1.005e+02",
    45  			node: NumberNode("", 100.5),
    46  		},
    47  		{
    48  			name: `[1,2,3]`,
    49  			node: ArrayNode("", []*Node{
    50  				NumberNode("0", 1),
    51  				NumberNode("2", 2),
    52  				NumberNode("3", 3),
    53  			}),
    54  		},
    55  	}
    56  	for _, test := range tests {
    57  		t.Run(test.name, func(t *testing.T) {
    58  			value, err := Marshal(test.node)
    59  			if err != nil {
    60  				t.Errorf("unexpected error: %s", err)
    61  			} else if string(value) != test.name {
    62  				t.Errorf("wrong result: '%s', expected '%s'", value, test.name)
    63  			}
    64  		})
    65  	}
    66  }
    67  
    68  func TestMarshal_Object(t *testing.T) {
    69  	node := ObjectNode("", map[string]*Node{
    70  		"foo": StringNode("foo", "bar"),
    71  		"baz": NumberNode("baz", 100500),
    72  		"qux": NullNode("qux"),
    73  	})
    74  
    75  	mustKey := []string{"foo", "baz", "qux"}
    76  
    77  	value, err := Marshal(node)
    78  	if err != nil {
    79  		t.Errorf("unexpected error: %s", err)
    80  	}
    81  
    82  	// the order of keys in the map is not guaranteed
    83  	// so we need to unmarshal the result and check the keys
    84  	decoded, err := Unmarshal(value)
    85  	if err != nil {
    86  		t.Errorf("unexpected error: %s", err)
    87  	}
    88  
    89  	for _, key := range mustKey {
    90  		if node, err := decoded.GetKey(key); err != nil {
    91  			t.Errorf("unexpected error: %s", err)
    92  		} else {
    93  			if node == nil {
    94  				t.Errorf("node is nil")
    95  			} else if node.key == nil {
    96  				t.Errorf("key is nil")
    97  			} else if *node.key != key {
    98  				t.Errorf("wrong key: '%s', expected '%s'", *node.key, key)
    99  			}
   100  		}
   101  	}
   102  }
   103  
   104  func valueNode(prev *Node, key string, typ ValueType, val interface{}) *Node {
   105  	curr := &Node{
   106  		prev:     prev,
   107  		data:     nil,
   108  		key:      &key,
   109  		borders:  [2]int{0, 0},
   110  		value:    val,
   111  		modified: true,
   112  	}
   113  
   114  	if val != nil {
   115  		curr.nodeType = typ
   116  	}
   117  
   118  	return curr
   119  }
   120  
   121  func TestMarshal_Errors(t *testing.T) {
   122  	tests := []struct {
   123  		name string
   124  		node func() (node *Node)
   125  	}{
   126  		{
   127  			name: "nil",
   128  			node: func() (node *Node) {
   129  				return
   130  			},
   131  		},
   132  		{
   133  			name: "broken",
   134  			node: func() (node *Node) {
   135  				node = Must(Unmarshal([]byte(`{}`)))
   136  				node.borders[1] = 0
   137  				return
   138  			},
   139  		},
   140  		{
   141  			name: "Numeric",
   142  			node: func() (node *Node) {
   143  				return valueNode(nil, "", Number, false)
   144  			},
   145  		},
   146  		{
   147  			name: "String",
   148  			node: func() (node *Node) {
   149  				return valueNode(nil, "", String, false)
   150  			},
   151  		},
   152  		{
   153  			name: "Bool",
   154  			node: func() (node *Node) {
   155  				return valueNode(nil, "", Boolean, 1)
   156  			},
   157  		},
   158  		{
   159  			name: "Array_1",
   160  			node: func() (node *Node) {
   161  				node = ArrayNode("", nil)
   162  				node.next["1"] = NullNode("1")
   163  				return
   164  			},
   165  		},
   166  		{
   167  			name: "Array_2",
   168  			node: func() (node *Node) {
   169  				return ArrayNode("", []*Node{valueNode(nil, "", Boolean, 1)})
   170  			},
   171  		},
   172  		{
   173  			name: "Object",
   174  			node: func() (node *Node) {
   175  				return ObjectNode("", map[string]*Node{"key": valueNode(nil, "key", Boolean, 1)})
   176  			},
   177  		},
   178  	}
   179  	for _, test := range tests {
   180  		t.Run(test.name, func(t *testing.T) {
   181  			value, err := Marshal(test.node())
   182  			if err == nil {
   183  				t.Errorf("expected error")
   184  			} else if len(value) != 0 {
   185  				t.Errorf("wrong result")
   186  			}
   187  		})
   188  	}
   189  }
   190  
   191  func TestMarshal_Nil(t *testing.T) {
   192  	_, err := Marshal(nil)
   193  	if err == nil {
   194  		t.Error("Expected error for nil node, but got nil")
   195  	}
   196  }
   197  
   198  func TestMarshal_NotModified(t *testing.T) {
   199  	node := &Node{}
   200  	_, err := Marshal(node)
   201  	if err == nil {
   202  		t.Error("Expected error for not modified node, but got nil")
   203  	}
   204  }
   205  
   206  func TestMarshalCycleReference(t *testing.T) {
   207  	node1 := &Node{
   208  		key:      stringPtr("node1"),
   209  		nodeType: String,
   210  		next: map[string]*Node{
   211  			"next": nil,
   212  		},
   213  	}
   214  
   215  	node2 := &Node{
   216  		key:      stringPtr("node2"),
   217  		nodeType: String,
   218  		prev:     node1,
   219  	}
   220  
   221  	node1.next["next"] = node2
   222  
   223  	_, err := Marshal(node1)
   224  	if err == nil {
   225  		t.Error("Expected error for cycle reference, but got nil")
   226  	}
   227  }
   228  
   229  func TestMarshalNoCycleReference(t *testing.T) {
   230  	node1 := &Node{
   231  		key:      stringPtr("node1"),
   232  		nodeType: String,
   233  		value:    "value1",
   234  		modified: true,
   235  	}
   236  
   237  	node2 := &Node{
   238  		key:      stringPtr("node2"),
   239  		nodeType: String,
   240  		value:    "value2",
   241  		modified: true,
   242  	}
   243  
   244  	_, err := Marshal(node1)
   245  	if err != nil {
   246  		t.Errorf("Unexpected error: %v", err)
   247  	}
   248  
   249  	_, err = Marshal(node2)
   250  	if err != nil {
   251  		t.Errorf("Unexpected error: %v", err)
   252  	}
   253  }
   254  
   255  func stringPtr(s string) *string {
   256  	return &s
   257  }