github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/pkg/webview/view_test.go (about)

     1  package webview
     2  
     3  import (
     4  	"bytes"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/grpc-ecosystem/grpc-gateway/runtime"
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/stretchr/testify/require"
    12  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    13  
    14  	"github.com/tilt-dev/tilt/internal/timecmp"
    15  	v1alpha1 "github.com/tilt-dev/tilt/pkg/apis/core/v1alpha1"
    16  )
    17  
    18  // Time serialization is a mess.
    19  //
    20  // There are basically two competing time serialization standards
    21  // that apimachinery uses.
    22  //
    23  // RFC 3339 (https://tools.ietf.org/html/rfc3339)
    24  // apimachinery uses this to serialize time in JSON
    25  // https://github.com/kubernetes/apimachinery/blob/v0.21.0/pkg/apis/meta/v1/time.go#L141
    26  //
    27  // protoreflect (the new Go V2 version of protobufs), which
    28  // insists on creating structs and using reflection.
    29  // apimachinery uses this to serialize time as (second, nanosecond) pairs
    30  // https://pkg.go.dev/k8s.io/apimachinery/pkg/apis/meta/v1#Timestamp
    31  //
    32  // These blow up jsonpb, which sometimes goes down the protoreflect
    33  // codepath and sometimes goes down the RFC3339 codepath.
    34  // Instead, we hack everything to serialize as RFC3339.
    35  
    36  func TestEncodeTimeJSONPB(t *testing.T) {
    37  	now := time.Unix(1620234922, 2000000)
    38  	time := metav1.NewTime(now)
    39  	assert.Equal(t, `"2021-05-05T17:15:22Z"
    40  `, encode(t, time))
    41  	assert.Equal(t, `"2021-05-05T17:15:22Z"
    42  `, encode(t, &time))
    43  }
    44  
    45  func TestDecodeUIBuildRunning(t *testing.T) {
    46  	build := v1alpha1.UIBuildRunning{}
    47  	decode(t, `{
    48    "startTime": "2021-05-05T17:15:22.002000Z"
    49  }`, &build)
    50  
    51  	timecmp.AssertTimeEqual(t, build.StartTime, time.Unix(1620234922, 2000000))
    52  }
    53  
    54  func TestEncodeUIBuildRunning(t *testing.T) {
    55  	now := time.Unix(1620234922, 2000000)
    56  	build := v1alpha1.UIBuildRunning{StartTime: metav1.NewMicroTime(now)}
    57  	assert.Equal(t, `{"startTime":"2021-05-05T17:15:22.002000Z"}
    58  `, encode(t, build))
    59  	assert.Equal(t, `{
    60    "startTime": "2021-05-05T17:15:22.002000Z"
    61  }
    62  `, encode(t, &build))
    63  }
    64  
    65  func TestEncodeMicroTimeJSONPB(t *testing.T) {
    66  	now := time.Unix(1620234922, 2000000)
    67  	time := metav1.NewMicroTime(now)
    68  	assert.Equal(t, `"2021-05-05T17:15:22.002000Z"
    69  `, encode(t, time))
    70  	assert.Equal(t, `"2021-05-05T17:15:22.002000Z"
    71  `, encode(t, &time))
    72  }
    73  
    74  func encode(t *testing.T, obj interface{}) string {
    75  	buf := bytes.NewBuffer(nil)
    76  	jsEncoder := &runtime.JSONPb{
    77  		OrigName: false,
    78  		Indent:   "  ",
    79  	}
    80  	require.NoError(t, jsEncoder.NewEncoder(buf).Encode(obj))
    81  	return buf.String()
    82  }
    83  
    84  func decode(t *testing.T, content string, v interface{}) {
    85  	jsEncoder := &runtime.JSONPb{
    86  		OrigName: false,
    87  		Indent:   "  ",
    88  	}
    89  	require.NoError(t, jsEncoder.NewDecoder(strings.NewReader(content)).Decode(v))
    90  }