github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/pkg/fftypes/timeutils_test.go (about)

     1  // Copyright © 2021 Kaleido, Inc.
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  package fftypes
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  type UTTimeTest struct {
    29  	T1 *FFTime `json:"t1"`
    30  	T2 *FFTime `json:"t2,omitempty"`
    31  	T3 *FFTime `json:"t3,omitempty"`
    32  	T4 *FFTime `json:"t4"`
    33  	T5 *FFTime `json:"t5,omitempty"`
    34  	T6 *FFTime `json:"t6,omitempty"`
    35  	T7 *FFTime `json:"t7,omitempty"`
    36  }
    37  
    38  func TestFFTimeJSONSerialization(t *testing.T) {
    39  	now := Now()
    40  	zeroTime := ZeroTime()
    41  	assert.True(t, time.Time(zeroTime).IsZero())
    42  	t6 := UnixTime(1621103852123456789)
    43  	t7 := UnixTime(1621103797)
    44  	utTimeTest := &UTTimeTest{
    45  		T1: nil,
    46  		T2: nil,
    47  		T3: &zeroTime,
    48  		T4: &zeroTime,
    49  		T5: now,
    50  		T6: t6,
    51  		T7: t7,
    52  	}
    53  	b, err := json.Marshal(&utTimeTest)
    54  	assert.NoError(t, err)
    55  	assert.Equal(t, fmt.Sprintf(
    56  		`{"t1":null,"t3":null,"t4":null,"t5":"%s","t6":"2021-05-15T18:37:32.123456789Z","t7":"2021-05-15T18:36:37Z"}`,
    57  		time.Time(*now).UTC().Format(time.RFC3339Nano)), string(b))
    58  
    59  	var utTimeTest2 UTTimeTest
    60  	err = json.Unmarshal(b, &utTimeTest2)
    61  	assert.NoError(t, err)
    62  	assert.Nil(t, utTimeTest.T1)
    63  	assert.Nil(t, utTimeTest.T2)
    64  	assert.Nil(t, nil, utTimeTest.T3)
    65  	assert.Nil(t, nil, utTimeTest.T4)
    66  	assert.Equal(t, *now, *utTimeTest.T5)
    67  	assert.Equal(t, *t6, *utTimeTest.T6)
    68  	assert.Equal(t, *t7, *utTimeTest.T7)
    69  }
    70  
    71  func TestFFTimeJSONUnmarshalFail(t *testing.T) {
    72  	var utTimeTest UTTimeTest
    73  	err := json.Unmarshal([]byte(`{"t1": "!Badness"}`), &utTimeTest)
    74  	assert.Regexp(t, "FF10165", err)
    75  }
    76  
    77  func TestFFTimeDatabaseSerialization(t *testing.T) {
    78  	now := Now()
    79  	zero := ZeroTime()
    80  
    81  	var ft *FFTime = &zero
    82  	v, err := ft.Value()
    83  	assert.NoError(t, err)
    84  	assert.Equal(t, int64(0), v)
    85  
    86  	ft = now
    87  	v, err = ft.Value()
    88  	assert.NoError(t, err)
    89  	assert.Equal(t, now.UnixNano(), v)
    90  
    91  	ft = UnixTime(1621103852123456789)
    92  	v, err = ft.Value()
    93  	assert.NoError(t, err)
    94  	assert.Equal(t, int64(1621103852123456789), v)
    95  
    96  	ft = UnixTime(1621103797)
    97  	v, err = ft.Value()
    98  	assert.NoError(t, err)
    99  	assert.Equal(t, int64(1621103797000000000), v)
   100  
   101  }
   102  
   103  func TestStringZero(t *testing.T) {
   104  	var ft *FFTime
   105  	assert.Equal(t, int64(0), ft.UnixNano())
   106  	zero := ZeroTime()
   107  	ft = &zero
   108  	assert.Equal(t, "", ft.String()) // empty string rather than epoch 1970 time
   109  }
   110  
   111  func TestFFTimeParseValue(t *testing.T) {
   112  
   113  	var ft FFTime
   114  
   115  	// Unix Nanosecs
   116  	err := ft.Scan("1621108144123456789")
   117  	assert.NoError(t, err)
   118  	assert.Equal(t, "2021-05-15T19:49:04.123456789Z", ft.String())
   119  
   120  	// Unix Millis
   121  	err = ft.Scan("1621108144123")
   122  	assert.NoError(t, err)
   123  	assert.Equal(t, "2021-05-15T19:49:04.123Z", ft.String())
   124  
   125  	// Unix Secs
   126  	err = ft.Scan("1621108144")
   127  	assert.NoError(t, err)
   128  	assert.Equal(t, "2021-05-15T19:49:04Z", ft.String())
   129  
   130  	// RFC3339 Secs - timezone to UTC
   131  	err = ft.Scan("2021-05-15T19:49:04-05:00")
   132  	assert.NoError(t, err)
   133  	assert.Equal(t, "2021-05-16T00:49:04Z", ft.String())
   134  
   135  	// RFC3339 Nanosecs
   136  	err = ft.Scan("2021-05-15T19:49:04.123456789Z")
   137  	assert.NoError(t, err)
   138  	assert.Equal(t, "2021-05-15T19:49:04.123456789Z", ft.String())
   139  
   140  	// A bad string
   141  	err = ft.Scan("!a supported time format")
   142  	assert.Regexp(t, "FF10165", err)
   143  
   144  	// Nil
   145  	err = ft.Scan(nil)
   146  	assert.NoError(t, nil, err)
   147  	assert.True(t, time.Time(ft).IsZero())
   148  
   149  	// Zero
   150  	err = ft.Scan(int64(0))
   151  	assert.NoError(t, nil, err)
   152  	assert.True(t, time.Time(ft).IsZero())
   153  
   154  	// Unix time
   155  	err = ft.Scan(int64(1621108144123))
   156  	assert.NoError(t, nil, err)
   157  	assert.Equal(t, "2021-05-15T19:49:04.123Z", ft.String())
   158  
   159  	// A bad type
   160  	err = ft.Scan(false)
   161  	assert.Regexp(t, "FF10125", err)
   162  
   163  }
   164  
   165  func TestFFDurationJSONSerialization(t *testing.T) {
   166  	var utDurationTest struct {
   167  		D1 *FFDuration `json:"d1"`
   168  		D2 *FFDuration `json:"d2,omitempty"`
   169  		D3 FFDuration  `json:"d3"`
   170  		D4 FFDuration  `json:"d4"`
   171  		D5 FFDuration  `json:"d5"`
   172  		D6 FFDuration  `json:"d6"`
   173  		D7 FFDuration  `json:"d7"`
   174  	}
   175  	jsonToParse := []byte(`
   176  	{
   177  		"d1": null,
   178  		"d3": 12345,
   179  		"d4": "12345",
   180  		"d5": "0",
   181  		"d6": "1h15s",
   182  		"d7": "-24h"
   183  	}
   184  	`)
   185  	err := json.Unmarshal(jsonToParse, &utDurationTest)
   186  	assert.NoError(t, err)
   187  	assert.Nil(t, utDurationTest.D1)
   188  	assert.Nil(t, utDurationTest.D2)
   189  	assert.Equal(t, FFDuration(12345)*FFDuration(time.Millisecond), utDurationTest.D3)
   190  	assert.Equal(t, FFDuration(12345)*FFDuration(time.Millisecond), utDurationTest.D4)
   191  	assert.Equal(t, FFDuration(0), utDurationTest.D5)
   192  	assert.Equal(t, FFDuration(1)*FFDuration(time.Hour)+FFDuration(15)*FFDuration(time.Second), utDurationTest.D6)
   193  	assert.Equal(t, FFDuration(-24)*FFDuration(time.Hour), utDurationTest.D7)
   194  
   195  	b, err := json.Marshal(&utDurationTest)
   196  	assert.NoError(t, err)
   197  	assert.Equal(t, `{"d1":null,"d3":"12.345s","d4":"12.345s","d5":"0s","d6":"1h0m15s","d7":"-24h0m0s"}`, string(b))
   198  
   199  	jsonToParse = []byte(`{"d1": false}`)
   200  	err = json.Unmarshal(jsonToParse, &utDurationTest)
   201  	assert.Error(t, err)
   202  
   203  	jsonToParse = []byte(`{"d1": "1 year"}`)
   204  	err = json.Unmarshal(jsonToParse, &utDurationTest)
   205  	assert.Error(t, err)
   206  }
   207  
   208  func TestFFDurationParseValue(t *testing.T) {
   209  
   210  	var fd FFDuration
   211  
   212  	err := fd.Scan("1h")
   213  	assert.NoError(t, err)
   214  	assert.Equal(t, "1h0m0s", fd.String())
   215  
   216  	err = fd.Scan(nil)
   217  	assert.NoError(t, err)
   218  	assert.Equal(t, FFDuration(0), fd)
   219  
   220  	err = fd.Scan(12345)
   221  	assert.NoError(t, err)
   222  	assert.Equal(t, FFDuration(12345)*FFDuration(time.Millisecond), fd)
   223  
   224  	err = fd.Scan(int64(12345))
   225  	assert.NoError(t, err)
   226  	assert.Equal(t, FFDuration(12345)*FFDuration(time.Millisecond), fd)
   227  
   228  	err = fd.Scan(false)
   229  	assert.Regexp(t, "FF10125", err)
   230  
   231  	err = fd.Scan("1 year")
   232  	assert.Regexp(t, "FF10167", err)
   233  
   234  	var pfd *FFDuration
   235  	v, err := pfd.Value()
   236  	assert.NoError(t, err)
   237  	assert.Equal(t, "", v)
   238  
   239  	pfd = &fd
   240  	*pfd = FFDuration(12345) * FFDuration(time.Millisecond)
   241  	v, err = pfd.Value()
   242  	assert.NoError(t, err)
   243  	assert.Equal(t, "12.345s", v)
   244  
   245  }
   246  
   247  func TestDurationParsing(t *testing.T) {
   248  	assert.Zero(t, ParseToDuration("!a duration"))
   249  	assert.Zero(t, ParseToDuration(""))
   250  	assert.Equal(t, "15ms", ParseToDuration("15ms").String())
   251  }