github.com/ncruces/go-sqlite3@v0.15.1-0.20240520133447-53eef1510ff0/error_test.go (about)

     1  package sqlite3
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/ncruces/go-sqlite3/internal/util"
     9  )
    10  
    11  func Test_assertErr(t *testing.T) {
    12  	err := util.AssertErr()
    13  	if s := err.Error(); !strings.HasPrefix(s, "sqlite3: assertion failed") || !strings.HasSuffix(s, "error_test.go:12)") {
    14  		t.Errorf("got %q", s)
    15  	}
    16  }
    17  
    18  func TestError(t *testing.T) {
    19  	t.Parallel()
    20  
    21  	var ecode ErrorCode
    22  	var xcode xErrorCode
    23  	err := &Error{code: 0x8080}
    24  	if !errors.As(err, &err) {
    25  		t.Fatal("want true")
    26  	}
    27  	if ecode := err.Code(); ecode != 0x80 {
    28  		t.Errorf("got %#x, want 0x80", uint8(ecode))
    29  	}
    30  	if ok := errors.As(err, &ecode); !ok || ecode != ErrorCode(0x80) {
    31  		t.Errorf("got %#x, want 0x80", uint8(ecode))
    32  	}
    33  	if !errors.Is(err, ErrorCode(0x80)) {
    34  		t.Errorf("want true")
    35  	}
    36  	if xcode := err.ExtendedCode(); xcode != 0x8080 {
    37  		t.Errorf("got %#x, want 0x8080", uint16(xcode))
    38  	}
    39  	if ok := errors.As(err, &xcode); !ok || xcode != xErrorCode(0x8080) {
    40  		t.Errorf("got %#x, want 0x8080", uint16(xcode))
    41  	}
    42  	if !errors.Is(err, xErrorCode(0x8080)) {
    43  		t.Errorf("want true")
    44  	}
    45  	if s := err.Error(); s != "sqlite3: 32896" {
    46  		t.Errorf("got %q", s)
    47  	}
    48  	if ok := errors.As(err.ExtendedCode(), &ecode); !ok || ecode != ErrorCode(0x80) {
    49  		t.Errorf("got %#x, want 0x80", uint8(ecode))
    50  	}
    51  	if !errors.Is(err.ExtendedCode(), ErrorCode(0x80)) {
    52  		t.Errorf("want true")
    53  	}
    54  }
    55  
    56  func TestError_Temporary(t *testing.T) {
    57  	t.Parallel()
    58  
    59  	tests := []struct {
    60  		name string
    61  		code uint64
    62  		want bool
    63  	}{
    64  		{"ERROR", uint64(ERROR), false},
    65  		{"BUSY", uint64(BUSY), true},
    66  		{"BUSY_RECOVERY", uint64(BUSY_RECOVERY), true},
    67  		{"BUSY_SNAPSHOT", uint64(BUSY_SNAPSHOT), true},
    68  		{"BUSY_TIMEOUT", uint64(BUSY_TIMEOUT), true},
    69  	}
    70  	for _, tt := range tests {
    71  		t.Run(tt.name, func(t *testing.T) {
    72  			{
    73  				err := &Error{code: tt.code}
    74  				if got := err.Temporary(); got != tt.want {
    75  					t.Errorf("Error.Temporary(%d) = %v, want %v", tt.code, got, tt.want)
    76  				}
    77  			}
    78  			{
    79  				err := ErrorCode(tt.code)
    80  				if got := err.Temporary(); got != tt.want {
    81  					t.Errorf("ErrorCode.Temporary(%d) = %v, want %v", tt.code, got, tt.want)
    82  				}
    83  			}
    84  			{
    85  				err := ExtendedErrorCode(tt.code)
    86  				if got := err.Temporary(); got != tt.want {
    87  					t.Errorf("ExtendedErrorCode.Temporary(%d) = %v, want %v", tt.code, got, tt.want)
    88  				}
    89  			}
    90  		})
    91  	}
    92  }
    93  
    94  func TestError_Timeout(t *testing.T) {
    95  	t.Parallel()
    96  
    97  	tests := []struct {
    98  		name string
    99  		code uint64
   100  		want bool
   101  	}{
   102  		{"ERROR", uint64(ERROR), false},
   103  		{"BUSY", uint64(BUSY), false},
   104  		{"BUSY_RECOVERY", uint64(BUSY_RECOVERY), false},
   105  		{"BUSY_SNAPSHOT", uint64(BUSY_SNAPSHOT), false},
   106  		{"BUSY_TIMEOUT", uint64(BUSY_TIMEOUT), true},
   107  	}
   108  	for _, tt := range tests {
   109  		t.Run(tt.name, func(t *testing.T) {
   110  			{
   111  				err := &Error{code: tt.code}
   112  				if got := err.Timeout(); got != tt.want {
   113  					t.Errorf("Error.Timeout(%d) = %v, want %v", tt.code, got, tt.want)
   114  				}
   115  			}
   116  			{
   117  				err := ExtendedErrorCode(tt.code)
   118  				if got := err.Timeout(); got != tt.want {
   119  					t.Errorf("Error.Timeout(%d) = %v, want %v", tt.code, got, tt.want)
   120  				}
   121  			}
   122  		})
   123  	}
   124  }
   125  
   126  func Test_ErrorCode_Error(t *testing.T) {
   127  	t.Parallel()
   128  
   129  	db, err := Open(":memory:")
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  	defer db.Close()
   134  
   135  	// Test all error codes.
   136  	for i := 0; i == int(ErrorCode(i)); i++ {
   137  		want := "sqlite3: "
   138  		r := db.call("sqlite3_errstr", uint64(i))
   139  		want += util.ReadString(db.mod, uint32(r), _MAX_NAME)
   140  
   141  		got := ErrorCode(i).Error()
   142  		if got != want {
   143  			t.Fatalf("got %q, want %q, with %d", got, want, i)
   144  		}
   145  	}
   146  }
   147  
   148  func Test_ExtendedErrorCode_Error(t *testing.T) {
   149  	t.Parallel()
   150  
   151  	db, err := Open(":memory:")
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  	defer db.Close()
   156  
   157  	// Test all extended error codes.
   158  	for i := 0; i == int(ExtendedErrorCode(i)); i++ {
   159  		want := "sqlite3: "
   160  		r := db.call("sqlite3_errstr", uint64(i))
   161  		want += util.ReadString(db.mod, uint32(r), _MAX_NAME)
   162  
   163  		got := ExtendedErrorCode(i).Error()
   164  		if got != want {
   165  			t.Fatalf("got %q, want %q, with %d", got, want, i)
   166  		}
   167  	}
   168  }