github.com/onflow/atree@v0.6.0/slab_test.go (about)

     1  /*
     2   * Atree - Scalable Arrays and Ordered Maps
     3   *
     4   * Copyright 2021 Dapper Labs, Inc.
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package atree
    20  
    21  import (
    22  	"testing"
    23  
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  func TestIsRootOfAnObject(t *testing.T) {
    28  	// We just need first 2 bytes of slab data to test.
    29  	testCases := []struct {
    30  		name   string
    31  		isRoot bool
    32  		data   []byte
    33  	}{
    34  		{name: "array data as root", isRoot: true, data: []byte{0x00, 0x80}},
    35  		{name: "array metadata as root", isRoot: true, data: []byte{0x00, 0x81}},
    36  		{name: "map data as root", isRoot: true, data: []byte{0x00, 0x88}},
    37  		{name: "map metadata as root", isRoot: true, data: []byte{0x00, 0x89}},
    38  		{name: "array data as non-root", isRoot: false, data: []byte{0x00, 0x00}},
    39  		{name: "array metadata as non-root", isRoot: false, data: []byte{0x00, 0x01}},
    40  		{name: "map data as non-root", isRoot: false, data: []byte{0x00, 0x08}},
    41  		{name: "map metadata as non-root", isRoot: false, data: []byte{0x00, 0x09}},
    42  	}
    43  
    44  	for _, tc := range testCases {
    45  		t.Run(tc.name, func(t *testing.T) {
    46  			isRoot, err := IsRootOfAnObject(tc.data)
    47  			require.NoError(t, err)
    48  			require.Equal(t, tc.isRoot, isRoot)
    49  		})
    50  	}
    51  
    52  	t.Run("data too short", func(t *testing.T) {
    53  		var fatalError *FatalError
    54  		var decodingError *DecodingError
    55  		var isRoot bool
    56  		var err error
    57  
    58  		isRoot, err = IsRootOfAnObject(nil)
    59  		require.False(t, isRoot)
    60  		require.Equal(t, 1, errorCategorizationCount(err))
    61  		require.ErrorAs(t, err, &fatalError)
    62  		require.ErrorAs(t, err, &decodingError)
    63  		require.ErrorAs(t, fatalError, &decodingError)
    64  
    65  		isRoot, err = IsRootOfAnObject([]byte{})
    66  		require.False(t, isRoot)
    67  		require.Equal(t, 1, errorCategorizationCount(err))
    68  		require.ErrorAs(t, err, &fatalError)
    69  		require.ErrorAs(t, err, &decodingError)
    70  		require.ErrorAs(t, fatalError, &decodingError)
    71  
    72  		isRoot, err = IsRootOfAnObject([]byte{0x00})
    73  		require.False(t, isRoot)
    74  		require.Equal(t, 1, errorCategorizationCount(err))
    75  		require.ErrorAs(t, err, &fatalError)
    76  		require.ErrorAs(t, err, &decodingError)
    77  		require.ErrorAs(t, fatalError, &decodingError)
    78  	})
    79  }
    80  
    81  func TestHasPointers(t *testing.T) {
    82  	// We just need first 2 bytes of slab data to test.
    83  	testCases := []struct {
    84  		name        string
    85  		hasPointers bool
    86  		data        []byte
    87  	}{
    88  		{name: "array data has pointer", hasPointers: true, data: []byte{0x00, 0x40}},
    89  		{name: "array metadata has pointer", hasPointers: true, data: []byte{0x00, 0x41}},
    90  		{name: "map data has pointer", hasPointers: true, data: []byte{0x00, 0x48}},
    91  		{name: "map metadata has pointer", hasPointers: true, data: []byte{0x00, 0x49}},
    92  		{name: "array data no pointer", hasPointers: false, data: []byte{0x00, 0x00}},
    93  		{name: "array metadata no pointer", hasPointers: false, data: []byte{0x00, 0x01}},
    94  		{name: "map data no pointer", hasPointers: false, data: []byte{0x00, 0x08}},
    95  		{name: "map metadata no pointer", hasPointers: false, data: []byte{0x00, 0x09}},
    96  	}
    97  
    98  	for _, tc := range testCases {
    99  		t.Run(tc.name, func(t *testing.T) {
   100  			hasPointers, err := HasPointers(tc.data)
   101  			require.NoError(t, err)
   102  			require.Equal(t, tc.hasPointers, hasPointers)
   103  		})
   104  	}
   105  
   106  	t.Run("data too short", func(t *testing.T) {
   107  		var fatalError *FatalError
   108  		var decodingError *DecodingError
   109  		var hasPointers bool
   110  		var err error
   111  
   112  		hasPointers, err = HasPointers(nil)
   113  		require.False(t, hasPointers)
   114  		require.Equal(t, 1, errorCategorizationCount(err))
   115  		require.ErrorAs(t, err, &fatalError)
   116  		require.ErrorAs(t, err, &decodingError)
   117  		require.ErrorAs(t, fatalError, &decodingError)
   118  
   119  		hasPointers, err = HasPointers([]byte{})
   120  		require.False(t, hasPointers)
   121  		require.Equal(t, 1, errorCategorizationCount(err))
   122  		require.ErrorAs(t, err, &fatalError)
   123  		require.ErrorAs(t, err, &decodingError)
   124  		require.ErrorAs(t, fatalError, &decodingError)
   125  
   126  		hasPointers, err = HasPointers([]byte{0x00})
   127  		require.False(t, hasPointers)
   128  		require.Equal(t, 1, errorCategorizationCount(err))
   129  		require.ErrorAs(t, err, &fatalError)
   130  		require.ErrorAs(t, err, &decodingError)
   131  		require.ErrorAs(t, fatalError, &decodingError)
   132  	})
   133  }
   134  
   135  func TestHasSizeLimit(t *testing.T) {
   136  	// We just need first 2 bytes of slab data to test.
   137  	testCases := []struct {
   138  		name         string
   139  		hasSizeLimit bool
   140  		data         []byte
   141  	}{
   142  		{name: "array data without size limit", hasSizeLimit: false, data: []byte{0x00, 0x20}},
   143  		{name: "array metadata without size limit", hasSizeLimit: false, data: []byte{0x00, 0x21}},
   144  		{name: "map data without size limit", hasSizeLimit: false, data: []byte{0x00, 0x28}},
   145  		{name: "map metadata without size limit", hasSizeLimit: false, data: []byte{0x00, 0x29}},
   146  		{name: "array data with size limit", hasSizeLimit: true, data: []byte{0x00, 0x00}},
   147  		{name: "array metadata with size limit", hasSizeLimit: true, data: []byte{0x00, 0x01}},
   148  		{name: "map data with size limit", hasSizeLimit: true, data: []byte{0x00, 0x08}},
   149  		{name: "map metadata with size limit", hasSizeLimit: true, data: []byte{0x00, 0x09}},
   150  	}
   151  
   152  	for _, tc := range testCases {
   153  		t.Run(tc.name, func(t *testing.T) {
   154  			hasSizeLimit, err := HasSizeLimit(tc.data)
   155  			require.NoError(t, err)
   156  			require.Equal(t, tc.hasSizeLimit, hasSizeLimit)
   157  		})
   158  	}
   159  
   160  	t.Run("data too short", func(t *testing.T) {
   161  		var fatalError *FatalError
   162  		var decodingError *DecodingError
   163  		var hasSizeLimit bool
   164  		var err error
   165  
   166  		hasSizeLimit, err = HasSizeLimit(nil)
   167  		require.False(t, hasSizeLimit)
   168  		require.Equal(t, 1, errorCategorizationCount(err))
   169  		require.ErrorAs(t, err, &fatalError)
   170  		require.ErrorAs(t, err, &decodingError)
   171  		require.ErrorAs(t, fatalError, &decodingError)
   172  
   173  		hasSizeLimit, err = HasSizeLimit([]byte{})
   174  		require.False(t, hasSizeLimit)
   175  		require.Equal(t, 1, errorCategorizationCount(err))
   176  		require.ErrorAs(t, err, &fatalError)
   177  		require.ErrorAs(t, err, &decodingError)
   178  		require.ErrorAs(t, fatalError, &decodingError)
   179  
   180  		hasSizeLimit, err = HasSizeLimit([]byte{0x00})
   181  		require.False(t, hasSizeLimit)
   182  		require.Equal(t, 1, errorCategorizationCount(err))
   183  		require.ErrorAs(t, err, &fatalError)
   184  		require.ErrorAs(t, err, &decodingError)
   185  		require.ErrorAs(t, fatalError, &decodingError)
   186  	})
   187  }