...

Source file src/github.com/go-openapi/strfmt/ulid_test.go

Documentation: github.com/go-openapi/strfmt

     1  package strfmt
     2  
     3  import (
     4  	"bytes"
     5  	"database/sql/driver"
     6  	"encoding/gob"
     7  	"fmt"
     8  	"sync"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  	"go.mongodb.org/mongo-driver/bson"
    14  )
    15  
    16  const testUlid = string("01EYXZVGBHG26MFTG4JWR4K558")
    17  const testUlidAlt = string("01EYXZW663G7PYHVSQ8WTMDA67")
    18  
    19  var testUlidOverrideMtx sync.Mutex
    20  var testUlidOverrideValMtx sync.Mutex
    21  
    22  func TestFormatULID_Text(t *testing.T) {
    23  	t.Parallel()
    24  
    25  	t.Run("positive", func(t *testing.T) {
    26  		t.Parallel()
    27  		ulid, err := ParseULID(testUlid)
    28  		require.NoError(t, err)
    29  
    30  		res, err := ulid.MarshalText()
    31  		require.NoError(t, err)
    32  		assert.Equal(t, testUlid, string(res))
    33  
    34  		ulid2, _ := ParseULID(testUlidAlt)
    35  		require.NoError(t, err)
    36  
    37  		what := []byte(testUlid)
    38  		err = ulid2.UnmarshalText(what)
    39  		require.NoError(t, err)
    40  		assert.Equal(t, testUlid, ulid2.String())
    41  	})
    42  	t.Run("negative", func(t *testing.T) {
    43  		t.Parallel()
    44  		ulid, err := ParseULID(testUlid)
    45  		require.NoError(t, err)
    46  
    47  		what := []byte("00000000-0000-0000-0000-000000000000")
    48  
    49  		err = ulid.UnmarshalText(what)
    50  		require.Error(t, err)
    51  	})
    52  }
    53  
    54  func TestFormatULID_BSON(t *testing.T) {
    55  	t.Parallel()
    56  	t.Run("positive", func(t *testing.T) {
    57  		t.Parallel()
    58  		ulid, _ := ParseULID(testUlid)
    59  
    60  		bsonData, err := bson.Marshal(&ulid)
    61  		require.NoError(t, err)
    62  
    63  		var ulidUnmarshaled ULID
    64  		err = bson.Unmarshal(bsonData, &ulidUnmarshaled)
    65  		require.NoError(t, err)
    66  		assert.Equal(t, ulid, ulidUnmarshaled)
    67  
    68  		// Check value marshaling explicitly
    69  		m := bson.M{"data": ulid}
    70  		bsonData, err = bson.Marshal(&m)
    71  		require.NoError(t, err)
    72  
    73  		var mUnmarshaled bson.M
    74  		err = bson.Unmarshal(bsonData, &mUnmarshaled)
    75  		require.NoError(t, err)
    76  
    77  		data, ok := m["data"].(ULID)
    78  		assert.True(t, ok)
    79  		assert.Equal(t, ulid, data)
    80  	})
    81  	t.Run("negative", func(t *testing.T) {
    82  		t.Parallel()
    83  		uuid := UUID("00000000-0000-0000-0000-000000000000")
    84  		bsonData, err := bson.Marshal(&uuid)
    85  		require.NoError(t, err)
    86  
    87  		var ulidUnmarshaled ULID
    88  		err = bson.Unmarshal(bsonData, &ulidUnmarshaled)
    89  		require.Error(t, err)
    90  	})
    91  }
    92  
    93  func TestFormatULID_JSON(t *testing.T) {
    94  	t.Parallel()
    95  	t.Run("positive", func(t *testing.T) {
    96  		t.Parallel()
    97  		ulid, err := ParseULID(testUlid)
    98  		require.NoError(t, err)
    99  
   100  		whatStr := fmt.Sprintf(`"%s"`, testUlidAlt)
   101  		what := []byte(whatStr)
   102  		err = ulid.UnmarshalJSON(what)
   103  		require.NoError(t, err)
   104  		assert.Equal(t, testUlidAlt, ulid.String())
   105  
   106  		data, err := ulid.MarshalJSON()
   107  		require.NoError(t, err)
   108  		assert.Equal(t, whatStr, string(data))
   109  	})
   110  	t.Run("null", func(t *testing.T) {
   111  		t.Parallel()
   112  		ulid, err := ParseULID(testUlid)
   113  		require.NoError(t, err)
   114  
   115  		err = ulid.UnmarshalJSON([]byte("null"))
   116  		require.NoError(t, err)
   117  	})
   118  	t.Run("negative", func(t *testing.T) {
   119  		t.Parallel()
   120  		// Check UnmarshalJSON failure with no lexed items
   121  		ulid := NewULIDZero()
   122  		err := ulid.UnmarshalJSON([]byte("zorg emperor"))
   123  		require.Error(t, err)
   124  
   125  		// Check lexer failure
   126  		err = ulid.UnmarshalJSON([]byte(`"zorg emperor"`))
   127  		require.Error(t, err)
   128  	})
   129  }
   130  
   131  func TestFormatULID_Scan(t *testing.T) {
   132  	t.Parallel()
   133  	t.Run("db.Scan", func(t *testing.T) {
   134  		t.Parallel()
   135  		testUlidOverrideMtx.Lock()
   136  		defer testUlidOverrideMtx.Unlock()
   137  
   138  		srcUlid := testUlidAlt
   139  
   140  		ulid, err := ParseULID(testUlid)
   141  		require.NoError(t, err)
   142  
   143  		err = ulid.Scan(srcUlid)
   144  		require.NoError(t, err)
   145  		assert.Equal(t, srcUlid, ulid.String())
   146  
   147  		ulid, _ = ParseULID(testUlid)
   148  		err = ulid.Scan([]byte(srcUlid))
   149  		require.NoError(t, err)
   150  		assert.Equal(t, srcUlid, ulid.String())
   151  	})
   152  	t.Run("db.Scan_Failed", func(t *testing.T) {
   153  		t.Parallel()
   154  		testUlidOverrideMtx.Lock()
   155  		defer testUlidOverrideMtx.Unlock()
   156  
   157  		ulid, err := ParseULID(testUlid)
   158  		zero := NewULIDZero()
   159  		require.NoError(t, err)
   160  
   161  		err = ulid.Scan(nil)
   162  		require.NoError(t, err)
   163  		assert.Equal(t, zero, ulid)
   164  
   165  		err = ulid.Scan("")
   166  		require.NoError(t, err)
   167  		assert.Equal(t, zero, ulid)
   168  
   169  		err = ulid.Scan(int64(0))
   170  		require.Error(t, err)
   171  
   172  		err = ulid.Scan(float64(0))
   173  		require.Error(t, err)
   174  	})
   175  	t.Run("db.Value", func(t *testing.T) {
   176  		t.Parallel()
   177  		testUlidOverrideValMtx.Lock()
   178  		defer testUlidOverrideValMtx.Unlock()
   179  
   180  		ulid, err := ParseULID(testUlid)
   181  		require.NoError(t, err)
   182  
   183  		val, err := ulid.Value()
   184  		require.NoError(t, err)
   185  
   186  		assert.EqualValues(t, testUlid, val)
   187  	})
   188  	t.Run("override.Scan", func(t *testing.T) {
   189  		t.Parallel()
   190  		testUlidOverrideMtx.Lock()
   191  		defer testUlidOverrideMtx.Unlock()
   192  
   193  		ulid, err := ParseULID(testUlid)
   194  		require.NoError(t, err)
   195  		ulid2, err := ParseULID(testUlidAlt)
   196  		require.NoError(t, err)
   197  
   198  		ULIDScanOverrideFunc = func(raw interface{}) (ULID, error) {
   199  			u := NewULIDZero()
   200  			switch x := raw.(type) {
   201  			case [16]byte:
   202  				return u, u.ULID.UnmarshalBinary(x[:])
   203  			case int: // just for linter
   204  				return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v", raw)
   205  			}
   206  			return u, fmt.Errorf("cannot sql.Scan() strfmt.ULID from: %#v", raw)
   207  		}
   208  
   209  		// get underlying binary implementation which is actually [16]byte
   210  		bytes := [16]byte(ulid.ULID)
   211  
   212  		err = ulid2.Scan(bytes)
   213  		require.NoError(t, err)
   214  		assert.Equal(t, ulid2, ulid)
   215  		assert.Equal(t, ulid2.String(), ulid.String())
   216  
   217  		// check other default cases became unreachable
   218  		err = ulid2.Scan(testUlid)
   219  		require.Error(t, err)
   220  
   221  		// return default Scan method
   222  		ULIDScanOverrideFunc = ULIDScanDefaultFunc
   223  		err = ulid2.Scan(testUlid)
   224  		require.NoError(t, err)
   225  		assert.Equal(t, testUlid, ulid2.String())
   226  	})
   227  	t.Run("override.Value", func(t *testing.T) {
   228  		t.Parallel()
   229  		testUlidOverrideValMtx.Lock()
   230  		defer testUlidOverrideValMtx.Unlock()
   231  
   232  		ulid, err := ParseULID(testUlid)
   233  		require.NoError(t, err)
   234  		ulid2, err := ParseULID(testUlid)
   235  		require.NoError(t, err)
   236  
   237  		ULIDValueOverrideFunc = func(u ULID) (driver.Value, error) {
   238  			bytes := [16]byte(u.ULID)
   239  			return driver.Value(bytes), nil
   240  		}
   241  
   242  		exp := [16]byte(ulid2.ULID)
   243  		val, err := ulid.Value()
   244  		require.NoError(t, err)
   245  
   246  		assert.EqualValues(t, exp, val)
   247  
   248  		// return default Value method
   249  		ULIDValueOverrideFunc = ULIDValueDefaultFunc
   250  
   251  		val, err = ulid.Value()
   252  		require.NoError(t, err)
   253  
   254  		assert.EqualValues(t, testUlid, val)
   255  	})
   256  }
   257  
   258  func TestFormatULID_DeepCopy(t *testing.T) {
   259  	ulid, err := ParseULID(testUlid)
   260  	require.NoError(t, err)
   261  	in := &ulid
   262  
   263  	out := new(ULID)
   264  	in.DeepCopyInto(out)
   265  	assert.Equal(t, in, out)
   266  
   267  	out2 := in.DeepCopy()
   268  	assert.Equal(t, in, out2)
   269  
   270  	var inNil *ULID
   271  	out3 := inNil.DeepCopy()
   272  	assert.Nil(t, out3)
   273  }
   274  
   275  func TestFormatULID_GobEncoding(t *testing.T) {
   276  	ulid, err := ParseULID(testUlid)
   277  	require.NoError(t, err)
   278  
   279  	b := bytes.Buffer{}
   280  	enc := gob.NewEncoder(&b)
   281  	err = enc.Encode(ulid)
   282  	require.NoError(t, err)
   283  	assert.NotEmpty(t, b.Bytes())
   284  
   285  	var result ULID
   286  
   287  	dec := gob.NewDecoder(&b)
   288  	err = dec.Decode(&result)
   289  	require.NoError(t, err)
   290  	assert.Equal(t, ulid, result)
   291  	assert.Equal(t, ulid.String(), result.String())
   292  }
   293  
   294  func TestFormatULID_NewULID_and_Equal(t *testing.T) {
   295  	t.Parallel()
   296  
   297  	ulid1, err := NewULID()
   298  	require.NoError(t, err)
   299  
   300  	ulid2, err := NewULID()
   301  	require.NoError(t, err)
   302  
   303  	//nolint:gocritic
   304  	assert.True(t, ulid1.Equal(ulid1), "ULID instances should be equal")
   305  	assert.False(t, ulid1.Equal(ulid2), "ULID instances should not be equal")
   306  
   307  	ulidZero := NewULIDZero()
   308  	ulidZero2 := NewULIDZero()
   309  	assert.True(t, ulidZero.Equal(ulidZero2), "ULID instances should be equal")
   310  }
   311  
   312  func TestIsULID(t *testing.T) {
   313  	t.Parallel()
   314  
   315  	tcases := []struct {
   316  		ulid   string
   317  		expect bool
   318  	}{
   319  		{ulid: "01EYXZVGBHG26MFTG4JWR4K558", expect: true},
   320  		{ulid: "01EYXZW663G7PYHVSQ8WTMDA67", expect: true},
   321  		{ulid: "7ZZZZZZZZZ0000000000000000", expect: true},
   322  		{ulid: "00000000000000000000000000", expect: true},
   323  		{ulid: "7ZZZZZZZZZZZZZZZZZZZZZZZZZ", expect: true},
   324  		{ulid: "not-a-ulid", expect: false},
   325  		{ulid: "8000000000FJ2MMFJ3ATV3XB2C", expect: false},
   326  		{ulid: "81EYY0NEYJZZZZZZZZZZZZZZZZ", expect: false},
   327  		{ulid: "7ZZZZZZZZZ000000000000000U", expect: false},
   328  		{ulid: "7ZZZZZZZZZ000000000000000L", expect: false},
   329  		{ulid: "7ZZZZZZZZZ000000000000000O", expect: false},
   330  		{ulid: "7ZZZZZZZZZ000000000000000I", expect: false},
   331  	}
   332  	for _, tcase := range tcases {
   333  		tc := tcase
   334  		t.Run(fmt.Sprintf("%s:%t", tc.ulid, tc.expect), func(t *testing.T) {
   335  			t.Parallel()
   336  			if tc.expect {
   337  				assert.True(t, IsULID(tc.ulid))
   338  			} else {
   339  				assert.False(t, IsULID(tc.ulid))
   340  			}
   341  		})
   342  	}
   343  
   344  }
   345  

View as plain text