github.com/arnodel/golua@v0.0.0-20230215163904-e0b5347eaaa1/runtime/value_test.go (about)

     1  package runtime
     2  
     3  import (
     4  	"reflect"
     5  	"strings"
     6  	"testing"
     7  )
     8  
     9  func BenchmarkValue(b *testing.B) {
    10  	for n := 0; n < b.N; n++ {
    11  		sv := IntValue(0)
    12  		for i := 0; i < 1000; i++ {
    13  			iv := IntValue(int64(i))
    14  			sv, _ = Add(sv, iv)
    15  		}
    16  	}
    17  }
    18  
    19  func BenchmarkAsCont(b *testing.B) {
    20  	v1 := ContValue(new(GoCont))
    21  	v2 := ContValue(new(LuaCont))
    22  	v3 := ContValue(new(Termination))
    23  	b.ResetTimer()
    24  	for i := 0; i < b.N; i++ {
    25  		_ = v1.AsCont()
    26  		_ = v2.AsCont()
    27  		_ = v3.AsCont()
    28  	}
    29  }
    30  
    31  func TestAsValue(t *testing.T) {
    32  	tests := []struct {
    33  		name string
    34  		arg  interface{}
    35  		want Value
    36  	}{
    37  		{
    38  			name: "nil arg",
    39  			want: NilValue,
    40  		},
    41  		{
    42  			name: "int64 arg",
    43  			arg:  int64(1555),
    44  			want: IntValue(1555),
    45  		},
    46  		{
    47  			name: "int arg",
    48  			arg:  int(999),
    49  			want: IntValue(999),
    50  		},
    51  		{
    52  			name: "float64 arg",
    53  			arg:  float64(0.9),
    54  			want: FloatValue(0.9),
    55  		},
    56  		{
    57  			name: "float32 arg",
    58  			arg:  float32(66),
    59  			want: FloatValue(66),
    60  		},
    61  		{
    62  			name: "bool arg",
    63  			arg:  true,
    64  			want: BoolValue(true),
    65  		},
    66  		{
    67  			name: "string arg",
    68  			arg:  "hello",
    69  			want: StringValue("hello"),
    70  		},
    71  		{
    72  			name: "other type",
    73  			arg:  []byte{'a'},
    74  			want: Value{iface: []byte{'a'}},
    75  		},
    76  	}
    77  	for _, tt := range tests {
    78  		t.Run(tt.name, func(t *testing.T) {
    79  			if got := AsValue(tt.arg); !reflect.DeepEqual(got, tt.want) {
    80  				t.Errorf("AsValue() = %v, want %v", got, tt.want)
    81  			}
    82  		})
    83  	}
    84  }
    85  
    86  func TestValue_Interface(t *testing.T) {
    87  
    88  	var tbl = NewTable()
    89  
    90  	tests := []struct {
    91  		name string
    92  		recv Value
    93  		want interface{}
    94  	}{
    95  		{
    96  			name: "nil",
    97  			recv: NilValue,
    98  			want: nil,
    99  		},
   100  		{
   101  			name: "int",
   102  			recv: IntValue(50),
   103  			want: int64(50),
   104  		},
   105  		{
   106  			name: "float",
   107  			recv: FloatValue(1.2),
   108  			want: float64(1.2),
   109  		},
   110  		{
   111  			name: "bool",
   112  			recv: BoolValue(false),
   113  			want: false,
   114  		},
   115  		{
   116  			name: "table value",
   117  			recv: TableValue(tbl),
   118  			want: tbl,
   119  		},
   120  	}
   121  	for _, tt := range tests {
   122  		t.Run(tt.name, func(t *testing.T) {
   123  			if got := tt.recv.Interface(); !reflect.DeepEqual(got, tt.want) {
   124  				t.Errorf("Value.Interface() = %v, want %v", got, tt.want)
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func TestValue_ToString(t *testing.T) {
   131  
   132  	tests := []struct {
   133  		name string
   134  		recv Value
   135  		want string
   136  		ok   bool
   137  	}{
   138  		{
   139  			name: "NilValue",
   140  			recv: NilValue,
   141  			want: "nil",
   142  		},
   143  		{
   144  			name: "IntValue",
   145  			recv: IntValue(456),
   146  			want: "456",
   147  			ok:   true,
   148  		},
   149  		{
   150  			name: "FloatValue",
   151  			recv: FloatValue(-1.5),
   152  			want: "-1.5",
   153  			ok:   true,
   154  		},
   155  		{
   156  			name: "StringValue",
   157  			recv: StringValue("a string"),
   158  			want: "a string",
   159  			ok:   true,
   160  		},
   161  		{
   162  			name: "TableValue",
   163  			recv: TableValue(NewTable()),
   164  			want: "table: 0x",
   165  		},
   166  		{
   167  			name: "CodeValue",
   168  			recv: CodeValue(nil),
   169  			want: "code: 0x0",
   170  		},
   171  		{
   172  			name: "GoFunction",
   173  			recv: FunctionValue(NewGoFunction(nil, "foo", 0, false)),
   174  			want: "gofunction: foo",
   175  		},
   176  		{
   177  			name: "Closure",
   178  			recv: FunctionValue((*Closure)(nil)),
   179  			want: "function: 0x0",
   180  		},
   181  		{
   182  			name: "Thread",
   183  			recv: ThreadValue((*Thread)(nil)),
   184  			want: "thread: 0x0",
   185  		},
   186  		{
   187  			name: "UserData",
   188  			recv: UserDataValue(NewUserData(nil, nil)),
   189  			want: "userdata: 0x",
   190  		},
   191  		{
   192  			name: "other type",
   193  			recv: AsValue(byte(123)),
   194  			want: "<unknown>",
   195  		},
   196  	}
   197  	for _, tt := range tests {
   198  		t.Run(tt.name, func(t *testing.T) {
   199  			got, got1 := tt.recv.ToString()
   200  			if !strings.HasPrefix(got, tt.want) {
   201  				t.Errorf("Value.ToString() got = %v, want %v", got, tt.want)
   202  			}
   203  			if got1 != tt.ok {
   204  				t.Errorf("Value.ToString() got1 = %v, want %v", got1, tt.ok)
   205  			}
   206  		})
   207  	}
   208  }
   209  
   210  func TestValue_AsCallable(t *testing.T) {
   211  	tests := []struct {
   212  		name   string
   213  		recv   Value
   214  		want   Callable
   215  		panics bool
   216  	}{
   217  		{
   218  			name: "Closure value ok",
   219  			recv: FunctionValue((*Closure)(nil)),
   220  			want: (*Closure)(nil),
   221  		},
   222  		{
   223  			name: "GoFunction value ok",
   224  			recv: FunctionValue((*GoFunction)(nil)),
   225  			want: (*GoFunction)(nil),
   226  		},
   227  		{
   228  			name:   "other type panics",
   229  			recv:   IntValue(5),
   230  			panics: true,
   231  		},
   232  	}
   233  	for _, tt := range tests {
   234  		t.Run(tt.name, func(t *testing.T) {
   235  			if tt.panics {
   236  				defer func() {
   237  					if r := recover(); r == nil {
   238  						t.Error("Expected panic")
   239  					}
   240  				}()
   241  			}
   242  			if got := tt.recv.AsCallable(); !reflect.DeepEqual(got, tt.want) {
   243  				t.Errorf("Value.AsCallable() = %v, want %v", got, tt.want)
   244  			}
   245  		})
   246  	}
   247  }