github.com/ipld/go-ipld-prime@v0.21.0/node/tests/mapSpecs.go (about)

     1  package tests
     2  
     3  import (
     4  	"testing"
     5  
     6  	qt "github.com/frankban/quicktest"
     7  
     8  	"github.com/ipld/go-ipld-prime/datamodel"
     9  	"github.com/ipld/go-ipld-prime/must"
    10  )
    11  
    12  func SpecTestMapStrInt(t *testing.T, np datamodel.NodePrototype) {
    13  	t.Run("map<str,int>, 3 entries", func(t *testing.T) {
    14  		n := buildMapStrIntN3(np)
    15  		t.Run("reads back out", func(t *testing.T) {
    16  			qt.Check(t, n.Length(), qt.Equals, int64(3))
    17  
    18  			v, err := n.LookupByString("whee")
    19  			qt.Check(t, err, qt.IsNil)
    20  			v2, err := v.AsInt()
    21  			qt.Check(t, err, qt.IsNil)
    22  			qt.Check(t, v2, qt.Equals, int64(1))
    23  
    24  			v, err = n.LookupByString("waga")
    25  			qt.Check(t, err, qt.IsNil)
    26  			v2, err = v.AsInt()
    27  			qt.Check(t, err, qt.IsNil)
    28  			qt.Check(t, v2, qt.Equals, int64(3))
    29  
    30  			v, err = n.LookupByString("woot")
    31  			qt.Check(t, err, qt.IsNil)
    32  			v2, err = v.AsInt()
    33  			qt.Check(t, err, qt.IsNil)
    34  			qt.Check(t, v2, qt.Equals, int64(2))
    35  		})
    36  		t.Run("reads via iteration", func(t *testing.T) {
    37  			itr := n.MapIterator()
    38  
    39  			qt.Check(t, itr.Done(), qt.IsFalse)
    40  			k, v, err := itr.Next()
    41  			qt.Check(t, err, qt.IsNil)
    42  			k2, err := k.AsString()
    43  			qt.Check(t, err, qt.IsNil)
    44  			qt.Check(t, k2, qt.Equals, "whee")
    45  			v2, err := v.AsInt()
    46  			qt.Check(t, err, qt.IsNil)
    47  			qt.Check(t, v2, qt.Equals, int64(1))
    48  
    49  			qt.Check(t, itr.Done(), qt.IsFalse)
    50  			k, v, err = itr.Next()
    51  			qt.Check(t, err, qt.IsNil)
    52  			k2, err = k.AsString()
    53  			qt.Check(t, err, qt.IsNil)
    54  			qt.Check(t, k2, qt.Equals, "woot")
    55  			v2, err = v.AsInt()
    56  			qt.Check(t, err, qt.IsNil)
    57  			qt.Check(t, v2, qt.Equals, int64(2))
    58  
    59  			qt.Check(t, itr.Done(), qt.IsFalse)
    60  			k, v, err = itr.Next()
    61  			qt.Check(t, err, qt.IsNil)
    62  			k2, err = k.AsString()
    63  			qt.Check(t, err, qt.IsNil)
    64  			qt.Check(t, k2, qt.Equals, "waga")
    65  			v2, err = v.AsInt()
    66  			qt.Check(t, err, qt.IsNil)
    67  			qt.Check(t, v2, qt.Equals, int64(3))
    68  
    69  			qt.Check(t, itr.Done(), qt.IsTrue)
    70  			k, v, err = itr.Next()
    71  			qt.Check(t, err, qt.Equals, datamodel.ErrIteratorOverread{})
    72  			qt.Check(t, k, qt.IsNil)
    73  			qt.Check(t, v, qt.IsNil)
    74  		})
    75  		t.Run("reads for absent keys error sensibly", func(t *testing.T) {
    76  			v, err := n.LookupByString("nope")
    77  			qt.Check(t, err, qt.ErrorAs, &datamodel.ErrNotExists{})
    78  			qt.Check(t, err, qt.ErrorMatches, `key not found: "nope"`)
    79  			qt.Check(t, v, qt.IsNil)
    80  		})
    81  	})
    82  	t.Run("repeated key should error", func(t *testing.T) {
    83  		nb := np.NewBuilder()
    84  		ma, err := nb.BeginMap(3)
    85  		if err != nil {
    86  			panic(err)
    87  		}
    88  		if err := ma.AssembleKey().AssignString("whee"); err != nil {
    89  			panic(err)
    90  		}
    91  		if err := ma.AssembleValue().AssignInt(1); err != nil {
    92  			panic(err)
    93  		}
    94  		if err := ma.AssembleKey().AssignString("whee"); err != nil {
    95  			qt.Check(t, err, qt.ErrorAs, &datamodel.ErrRepeatedMapKey{})
    96  			// No string assertion at present -- how that should be presented for typed stuff is unsettled
    97  			//  (and if it's clever, it'll differ from untyped, which will mean no assertion possible!).
    98  		}
    99  	})
   100  	t.Run("using expired child assemblers should panic", func(t *testing.T) {
   101  		nb := np.NewBuilder()
   102  		ma, err := nb.BeginMap(3)
   103  		must.NotError(err)
   104  
   105  		// Assemble a key, and then try to assign it again.  Latter should fail.
   106  		ka := ma.AssembleKey()
   107  		must.NotError(ka.AssignString("whee"))
   108  		func() {
   109  			defer func() { recover() }()
   110  			ka.AssignString("woo")
   111  			t.Fatal("must not be reached")
   112  		}()
   113  
   114  		// Assemble a value, and then try to assign it again.  Latter should fail.
   115  		// (This does assume your system can continue after disregarding the last error.)
   116  		va := ma.AssembleValue()
   117  		must.NotError(va.AssignInt(1))
   118  		func() {
   119  			defer func() { recover() }()
   120  			va.AssignInt(2)
   121  			t.Fatal("must not be reached")
   122  		}()
   123  
   124  		// ... and neither of these should've had visible effects!
   125  		qt.Check(t, ma.Finish(), qt.IsNil)
   126  		n := nb.Build()
   127  		qt.Check(t, n.Length(), qt.Equals, int64(1))
   128  		v, err := n.LookupByString("whee")
   129  		qt.Check(t, err, qt.IsNil)
   130  		v2, err := v.AsInt()
   131  		qt.Check(t, err, qt.IsNil)
   132  		qt.Check(t, v2, qt.Equals, int64(1))
   133  	})
   134  	t.Run("builder reset works", func(t *testing.T) {
   135  		// TODO
   136  	})
   137  }
   138  
   139  func SpecTestMapStrMapStrInt(t *testing.T, np datamodel.NodePrototype) {
   140  	t.Run("map<str,map<str,int>>", func(t *testing.T) {
   141  		nb := np.NewBuilder()
   142  		ma, err := nb.BeginMap(3)
   143  		must.NotError(err)
   144  		must.NotError(ma.AssembleKey().AssignString("whee"))
   145  		func(ma datamodel.MapAssembler, err error) {
   146  			must.NotError(ma.AssembleKey().AssignString("m1k1"))
   147  			must.NotError(ma.AssembleValue().AssignInt(1))
   148  			must.NotError(ma.AssembleKey().AssignString("m1k2"))
   149  			must.NotError(ma.AssembleValue().AssignInt(2))
   150  			must.NotError(ma.Finish())
   151  		}(ma.AssembleValue().BeginMap(2))
   152  		must.NotError(ma.AssembleKey().AssignString("woot"))
   153  		func(ma datamodel.MapAssembler, err error) {
   154  			must.NotError(ma.AssembleKey().AssignString("m2k1"))
   155  			must.NotError(ma.AssembleValue().AssignInt(3))
   156  			must.NotError(ma.AssembleKey().AssignString("m2k2"))
   157  			must.NotError(ma.AssembleValue().AssignInt(4))
   158  			must.NotError(ma.Finish())
   159  		}(ma.AssembleValue().BeginMap(2))
   160  		must.NotError(ma.AssembleKey().AssignString("waga"))
   161  		func(ma datamodel.MapAssembler, err error) {
   162  			must.NotError(ma.AssembleKey().AssignString("m3k1"))
   163  			must.NotError(ma.AssembleValue().AssignInt(5))
   164  			must.NotError(ma.AssembleKey().AssignString("m3k2"))
   165  			must.NotError(ma.AssembleValue().AssignInt(6))
   166  			must.NotError(ma.Finish())
   167  		}(ma.AssembleValue().BeginMap(2))
   168  		must.NotError(ma.Finish())
   169  		n := nb.Build()
   170  
   171  		t.Run("reads back out", func(t *testing.T) {
   172  			qt.Check(t, n.Length(), qt.Equals, int64(3))
   173  
   174  			v, err := n.LookupByString("woot")
   175  			qt.Check(t, err, qt.IsNil)
   176  			v2, err := v.LookupByString("m2k1")
   177  			qt.Check(t, err, qt.IsNil)
   178  			v3, err := v2.AsInt()
   179  			qt.Check(t, err, qt.IsNil)
   180  			qt.Check(t, v3, qt.Equals, int64(3))
   181  			v2, err = v.LookupByString("m2k2")
   182  			qt.Check(t, err, qt.IsNil)
   183  			v3, err = v2.AsInt()
   184  			qt.Check(t, err, qt.IsNil)
   185  			qt.Check(t, v3, qt.Equals, int64(4))
   186  		})
   187  	})
   188  }
   189  
   190  func SpecTestMapStrListStr(t *testing.T, np datamodel.NodePrototype) {
   191  	t.Run("map<str,list<str>>", func(t *testing.T) {
   192  		nb := np.NewBuilder()
   193  		ma, err := nb.BeginMap(3)
   194  		must.NotError(err)
   195  		must.NotError(ma.AssembleKey().AssignString("asdf"))
   196  		func(la datamodel.ListAssembler, err error) {
   197  			must.NotError(la.AssembleValue().AssignString("eleven"))
   198  			must.NotError(la.AssembleValue().AssignString("twelve"))
   199  			must.NotError(la.AssembleValue().AssignString("thirteen"))
   200  			must.NotError(la.Finish())
   201  		}(ma.AssembleValue().BeginList(3))
   202  		must.NotError(ma.AssembleKey().AssignString("qwer"))
   203  		func(la datamodel.ListAssembler, err error) {
   204  			must.NotError(la.AssembleValue().AssignString("twentyone"))
   205  			must.NotError(la.AssembleValue().AssignString("twentytwo"))
   206  			must.NotError(la.Finish())
   207  		}(ma.AssembleValue().BeginList(2))
   208  		must.NotError(ma.AssembleKey().AssignString("zxcv"))
   209  		func(la datamodel.ListAssembler, err error) {
   210  			must.NotError(la.AssembleValue().AssignString("thirtyone"))
   211  			must.NotError(la.Finish())
   212  		}(ma.AssembleValue().BeginList(1))
   213  		must.NotError(ma.Finish())
   214  		n := nb.Build()
   215  
   216  		t.Run("reads back out", func(t *testing.T) {
   217  			qt.Check(t, n.Length(), qt.Equals, int64(3))
   218  
   219  			v, err := n.LookupByString("qwer")
   220  			qt.Check(t, err, qt.IsNil)
   221  			v2, err := v.LookupByIndex(1)
   222  			qt.Check(t, err, qt.IsNil)
   223  			v3, err := v2.AsString()
   224  			qt.Check(t, err, qt.IsNil)
   225  			qt.Check(t, v3, qt.Equals, "twentytwo")
   226  		})
   227  	})
   228  }