<commit_before>package ffi_test

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/sbinet/go-ffi/pkg/ffi"
)

func TestBuiltinTypes(t *testing.T) {
	for _, table := range []struct {
		n  string
		t  ffi.Type
		rt reflect.Type
	}{
		{"unsigned char", ffi.C_uchar, reflect.TypeOf(byte(0))},
		{"char", ffi.C_char, reflect.TypeOf(byte(0))},

		{"int8", ffi.C_int8, reflect.TypeOf(int8(0))},
		{"uint8", ffi.C_uint8, reflect.TypeOf(uint8(0))},
		{"int16", ffi.C_int16, reflect.TypeOf(int16(0))},
		{"uint16", ffi.C_uint16, reflect.TypeOf(uint16(0))},
		{"int32", ffi.C_int32, reflect.TypeOf(int32(0))},
		{"uint32", ffi.C_uint32, reflect.TypeOf(uint32(0))},
		{"int64", ffi.C_int64, reflect.TypeOf(int64(0))},
		{"uint64", ffi.C_uint64, reflect.TypeOf(uint64(0))},

		{"float", ffi.C_float, reflect.TypeOf(float32(0))},
		{"double", ffi.C_double, reflect.TypeOf(float64(0))},
		//FIXME: use float128 when/if available
		//{"long double", ffi.C_longdouble, reflect.TypeOf(complex128(0))},

		{"*", ffi.C_pointer, reflect.TypeOf((*int)(nil))},
	} {
		if table.n != table.t.Name() {
			t.Errorf("expected [%s], got [%s]", table.n, table.t.Name())
		}
		if table.t.Size() != table.rt.Size() {
			t.Errorf("expected [%d], got [%d] (type=%q)", table.t.Size(), table.rt.Size(), table.n)
		}
	}
}

func TestNewStructType(t *testing.T) {

	arr10, err := ffi.NewArrayType(10, ffi.C_int32)
	if err != nil {
		t.Errorf(err.Error())
	}

	for _, table := range []struct {
		name    string
		fields  []ffi.Field
		size    uintptr
		offsets []uintptr
	}{
		{"struct_0",
			[]ffi.Field{{"a", ffi.C_int}},
			ffi.C_int.Size(),
			[]uintptr{0},
		},
		{"struct_1",
			[]ffi.Field{
				{"a", ffi.C_int},
				{"b", ffi.C_int},
			},
			ffi.C_int.Size() + ffi.C_int.Size(),
			[]uintptr{0, ffi.C_int.Size()},
		},
		{"struct_2",
			[]ffi.Field{
				{"F1", ffi.C_uint8},
				{"F2", ffi.C_int16},
				{"F3", ffi.C_int32},
				{"F4", ffi.C_uint8},
			},
			12,
			[]uintptr{0, 2, 4, 8},
		},
		{"struct_3",
			[]ffi.Field{
				{"F1", ffi.C_uint8},
				{"F2", arr10},
				{"F3", ffi.C_int32},
				{"F4", ffi.C_uint8},
			},
			56,
			[]uintptr{0, 8, 48, 52},
		},
	} {
		typ, err := ffi.NewStructType(table.name, table.fields)
		if err != nil {
			t.Errorf(err.Error())
		}
		eq(t, table.name, typ.Name())
		//eq(t, table.size, typ.Size())
		if table.size != typ.Size() {
			t.Errorf("expected size [%d] got [%d] (type=%q)", table.size, typ.Size(), table.name)
		}
		eq(t, len(table.offsets), typ.NumField())
		for i := 0; i < typ.NumField(); i++ {
			if table.offsets[i] != typ.Field(i).Offset {<commit_msg>type_test: temporarily disable alignment/offset test. need better testing 32b/64b<commit_after>package ffi_test

import (
	"fmt"
	"reflect"
	"testing"

	"github.com/sbinet/go-ffi/pkg/ffi"
)

func TestBuiltinTypes(t *testing.T) {
	for _, table := range []struct {
		n  string
		t  ffi.Type
		rt reflect.Type
	}{
		{"unsigned char", ffi.C_uchar, reflect.TypeOf(byte(0))},
		{"char", ffi.C_char, reflect.TypeOf(byte(0))},

		{"int8", ffi.C_int8, reflect.TypeOf(int8(0))},
		{"uint8", ffi.C_uint8, reflect.TypeOf(uint8(0))},
		{"int16", ffi.C_int16, reflect.TypeOf(int16(0))},
		{"uint16", ffi.C_uint16, reflect.TypeOf(uint16(0))},
		{"int32", ffi.C_int32, reflect.TypeOf(int32(0))},
		{"uint32", ffi.C_uint32, reflect.TypeOf(uint32(0))},
		{"int64", ffi.C_int64, reflect.TypeOf(int64(0))},
		{"uint64", ffi.C_uint64, reflect.TypeOf(uint64(0))},

		{"float", ffi.C_float, reflect.TypeOf(float32(0))},
		{"double", ffi.C_double, reflect.TypeOf(float64(0))},
		//FIXME: use float128 when/if available
		//{"long double", ffi.C_longdouble, reflect.TypeOf(complex128(0))},

		{"*", ffi.C_pointer, reflect.TypeOf((*int)(nil))},
	} {
		if table.n != table.t.Name() {
			t.Errorf("expected [%s], got [%s]", table.n, table.t.Name())
		}
		if table.t.Size() != table.rt.Size() {
			t.Errorf("expected [%d], got [%d] (type=%q)", table.t.Size(), table.rt.Size(), table.n)
		}
	}
}

func TestNewStructType(t *testing.T) {

	arr10, err := ffi.NewArrayType(10, ffi.C_int32)
	if err != nil {
		t.Errorf(err.Error())
	}
	eq(t, int(10), arr10.Len())

	for _, table := range []struct {
		name    string
		fields  []ffi.Field
		size    uintptr
		offsets []uintptr
	}{
		{"struct_0",
			[]ffi.Field{{"a", ffi.C_int}},
			ffi.C_int.Size(),
			[]uintptr{0},
		},
		{"struct_1",
			[]ffi.Field{
				{"a", ffi.C_int},
				{"b", ffi.C_int},
			},
			ffi.C_int.Size() + ffi.C_int.Size(),
			[]uintptr{0, ffi.C_int.Size()},
		},
		{"struct_2",
			[]ffi.Field{
				{"F1", ffi.C_uint8},
				{"F2", ffi.C_int16},
				{"F3", ffi.C_int32},
				{"F4", ffi.C_uint8},
			},
			12,
			[]uintptr{0, 2, 4, 8},
		},
		//FIXME: 32b/64b alignement differ!!
		// make 2 tests!
		// {"struct_3",
		// 	[]ffi.Field{
		// 		{"F1", ffi.C_uint8},
		// 		{"F2", arr10},
		// 		{"F3", ffi.C_int32},
		// 		{"F4", ffi.C_uint8},
		// 	},
		// 	56,
		// 	[]uintptr{0, 8, 48, 52},
		// },
	} {
		typ, err := ffi.NewStructType(table.name, table.fields)
		if err != nil {
			t.Errorf(err.Error())
		}
		eq(t, table.name, typ.Name())
		//eq(t, table.size, typ.Size())
		if table.size != typ.Size() {
			t.Errorf("expected size [%d] got [%d] (type=%q)", table.size, typ.Size(), table.name)
		}
		eq(t, len(table.offsets), typ.NumField())
		for i := 0; i < typ.NumField(); i++ {
			if table.offsets[i] != typ.Field(i).Offset {
{'fraction_non_alphanumeric': 0.23469960696238068, 'fraction_numerical': 0.04435710275126333, 'mean_word_length': 3.423841059602649, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5590338', 'n_tokens_mistral': 2719, 'n_tokens_neox': 2393, 'n_words': 406}