github.com/teh-cmc/mmm@v0.0.0-20160717174312-f3d5d92d1c27/mmm_test.go (about)

     1  // Copyright © 2015 Clement 'cmc' Rey <cr.rey.clement@gmail.com>.
     2  //
     3  // Use of this source code is governed by an MIT-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package mmm
     7  
     8  import (
     9  	"fmt"
    10  	"log"
    11  	"runtime"
    12  	"testing"
    13  	"unsafe"
    14  )
    15  
    16  // -----------------------------------------------------------------------------
    17  
    18  type Coordinate struct {
    19  	x, y int
    20  }
    21  
    22  func Example_simple_usage() {
    23  	// create a new memory chunk that contains 3 Coordinate structures
    24  	mc, err := NewMemChunk(Coordinate{}, 3)
    25  	if err != nil {
    26  		log.Fatal(err)
    27  	}
    28  
    29  	// print 3
    30  	fmt.Println(mc.NbObjects())
    31  
    32  	// write {3,9} at index 0, then print {3,9}
    33  	fmt.Println(mc.Write(0, Coordinate{3, 9}))
    34  	// write {17,2} at index 1, then print {17,2}
    35  	fmt.Println(mc.Write(1, Coordinate{17, 2}))
    36  	// write {42,42} at index 2, then print {42,42}
    37  	fmt.Println(mc.Write(2, Coordinate{42, 42}))
    38  
    39  	// print {17,2}
    40  	fmt.Println(mc.Read(1))
    41  	// print {42,42}
    42  	fmt.Println(*((*Coordinate)(unsafe.Pointer(mc.Pointer(2)))))
    43  
    44  	// free memory chunk
    45  	if err := mc.Delete(); err != nil {
    46  		log.Fatal(err)
    47  	}
    48  
    49  	// Output:
    50  	// 3
    51  	// {3 9}
    52  	// {17 2}
    53  	// {42 42}
    54  	// {17 2}
    55  	// {42 42}
    56  }
    57  
    58  // TestNewMemChunk tests the NewMemChunk function.
    59  func TestNewMemChunk(t *testing.T) {
    60  	// can't create 0-length chunk
    61  	_, err := NewMemChunk(nil, 0)
    62  	if err.Error() != "`n` must be > 0" {
    63  		t.Error("expected length error, got", err)
    64  	}
    65  
    66  	types := []interface{}{
    67  		// interface
    68  		interface{}(0),
    69  		// boolean
    70  		false,
    71  		// numeric
    72  		byte(0),
    73  		int(0),
    74  		uint(0),
    75  		uintptr(0),
    76  		// array
    77  		[3]int{},
    78  		// unsafe pointer
    79  		unsafe.Pointer(new(int)),
    80  	}
    81  	for _, typ := range types {
    82  		// create chunk of type
    83  		mc, err := NewMemChunk(typ, 1)
    84  		if err != nil {
    85  			t.Fatal(err)
    86  		}
    87  		// Read should produce input value
    88  		if mc.Read(0) != typ {
    89  			t.Error(typ)
    90  		}
    91  		mc.Delete()
    92  	}
    93  
    94  	invalidTypes := []interface{}{
    95  		// nil pointer
    96  		nil,
    97  		// non-nil pointer
    98  		new(int),
    99  		// slice
   100  		[]int{},
   101  		// array of invalid type
   102  		[3]*int{},
   103  		// struct with invalid type
   104  		struct {
   105  			valid   int
   106  			invalid *int
   107  		}{},
   108  	}
   109  	for _, typ := range invalidTypes {
   110  		// create chunk of type
   111  		_, err := NewMemChunk(typ, 1)
   112  		if err == nil {
   113  			t.Fatal("expected error, got nil")
   114  		}
   115  	}
   116  
   117  	// run GC cycle; finalizers should run
   118  	runtime.GC()
   119  }