github.com/jordan-bonecutter/can-go@v0.0.0-20230901155856-d83995b18e50/frame_json_test.go (about)

     1  package can
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"math/rand"
     7  	"reflect"
     8  	"testing"
     9  	"testing/quick"
    10  
    11  	"gotest.tools/v3/assert"
    12  	is "gotest.tools/v3/assert/cmp"
    13  )
    14  
    15  func TestFrame_JSON(t *testing.T) {
    16  	for _, tt := range []struct {
    17  		jsonFrame string
    18  		frame     Frame
    19  	}{
    20  		{
    21  			// Standard frame
    22  			jsonFrame: `{"id":42,"data":"00010203"}`,
    23  			frame: Frame{
    24  				ID:     42,
    25  				Length: 4,
    26  				Data:   Data{0x00, 0x01, 0x02, 0x03},
    27  			},
    28  		},
    29  		{
    30  			// Standard frame, no data
    31  			jsonFrame: `{"id":42}`,
    32  			frame:     Frame{ID: 42},
    33  		},
    34  		{
    35  			// Standard remote frame
    36  			jsonFrame: `{"id":42,"remote":true,"length":4}`,
    37  			frame: Frame{
    38  				ID:       42,
    39  				IsRemote: true,
    40  				Length:   4,
    41  			},
    42  		},
    43  		{
    44  			// Extended frame
    45  			jsonFrame: `{"id":42,"data":"0001020304050607","extended":true}`,
    46  			frame: Frame{
    47  				ID:         42,
    48  				IsExtended: true,
    49  				Length:     8,
    50  				Data:       Data{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07},
    51  			},
    52  		},
    53  		{
    54  			// Extended frame, no data
    55  			jsonFrame: `{"id":42,"extended":true}`,
    56  			frame:     Frame{ID: 42, IsExtended: true},
    57  		},
    58  		{
    59  			// Extended remote frame
    60  			jsonFrame: `{"id":42,"extended":true,"remote":true,"length":8}`,
    61  			frame: Frame{
    62  				ID:         42,
    63  				IsExtended: true,
    64  				IsRemote:   true,
    65  				Length:     8,
    66  			},
    67  		},
    68  	} {
    69  		tt := tt
    70  		t.Run(fmt.Sprintf("JSON|frame=%v", tt.frame), func(t *testing.T) {
    71  			assert.Check(t, is.Equal(tt.jsonFrame, tt.frame.JSON()))
    72  		})
    73  		t.Run(fmt.Sprintf("UnmarshalJSON|frame=%v", tt.frame), func(t *testing.T) {
    74  			var frame Frame
    75  			if err := json.Unmarshal([]byte(tt.jsonFrame), &frame); err != nil {
    76  				t.Fatal(err)
    77  			}
    78  			assert.Check(t, is.DeepEqual(tt.frame, frame))
    79  		})
    80  	}
    81  }
    82  
    83  func TestFrame_UnmarshalJSON_Invalid(t *testing.T) {
    84  	var f Frame
    85  	t.Run("invalid JSON", func(t *testing.T) {
    86  		data := `foobar`
    87  		assert.Check(t, f.UnmarshalJSON([]uint8(data)) != nil)
    88  	})
    89  	t.Run("invalid payload", func(t *testing.T) {
    90  		data := `{"id":1,"data":"foobar","extended":false,"remote":false}`
    91  		assert.Check(t, f.UnmarshalJSON([]uint8(data)) != nil)
    92  	})
    93  }
    94  
    95  func (Frame) Generate(rand *rand.Rand, _ int) reflect.Value {
    96  	f := Frame{
    97  		IsExtended: rand.Intn(2) == 0,
    98  		IsRemote:   rand.Intn(2) == 0,
    99  	}
   100  	if f.IsExtended {
   101  		f.ID = rand.Uint32() & MaxExtendedID
   102  	} else {
   103  		f.ID = rand.Uint32() & MaxID
   104  	}
   105  	f.Length = uint8(rand.Intn(9))
   106  	if !f.IsRemote {
   107  		_, _ = rand.Read(f.Data[:f.Length])
   108  	}
   109  	return reflect.ValueOf(f)
   110  }
   111  
   112  func TestPropertyFrame_MarshalUnmarshalJSON(t *testing.T) {
   113  	f := func(f Frame) Frame {
   114  		return f
   115  	}
   116  	g := func(f Frame) Frame {
   117  		f2 := Frame{}
   118  		if err := json.Unmarshal([]uint8(f.JSON()), &f2); err != nil {
   119  			t.Fatal(err)
   120  		}
   121  		return f2
   122  	}
   123  	if err := quick.CheckEqual(f, g, nil); err != nil {
   124  		t.Fatal(err)
   125  	}
   126  }