diff --git a/cmd/dialects-gen/main.go b/cmd/dialects-gen/main.go index eef2e9bc2..c4804eb18 100644 --- a/cmd/dialects-gen/main.go +++ b/cmd/dialects-gen/main.go @@ -18,27 +18,15 @@ var tplTest = template.Must(template.New("").Parse( package dialects import ( - "testing" - "encoding" - "reflect" + "testing" + "encoding" + "reflect" - "github.com/stretchr/testify/require" + "github.com/stretchr/testify/require" - "github.com/bluenviron/gomavlib/v3/pkg/dialect" -{{- range .Dialects }} - "github.com/bluenviron/gomavlib/v3/pkg/dialects/{{ . }}" -{{- end }} + "github.com/bluenviron/gomavlib/v3/pkg/dialects/common" ) -func TestDialects(t *testing.T) { -{{- range .Dialects }} - func() { - _, err := dialect.NewReadWriter({{ . }}.Dialect) - require.NoError(t, err) - }() -{{- end }} -} - var casesEnum = []struct { name string dec encoding.TextMarshaler @@ -78,6 +66,42 @@ func TestEnumMarshalText(t *testing.T) { } `)) +var tplDialectTest = template.Must(template.New("").Parse( + `//autogenerated:yes +//nolint:revive +package {{ .PkgName }} + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/bluenviron/gomavlib/v3/pkg/dialect" +) + +func TestDialect(t *testing.T) { + _, err := dialect.NewReadWriter(Dialect) + require.NoError(t, err) +} +`)) + +var tplEnumTest = template.Must(template.New("").Parse( + `//autogenerated:yes +//nolint:revive,govet,errcheck +package {{ .PkgName }} + +import ( + "testing" +) + +func TestEnum_{{ .Name }}(t *testing.T) { + var e {{ .Name }} + e.UnmarshalText([]byte{}) + e.MarshalText() + e.String() +} +`)) + func writeTemplate(fpath string, tpl *template.Template, args map[string]interface{}) error { f, err := os.Create(fpath) if err != nil { @@ -121,6 +145,55 @@ func processDialect(commit string, name string) error { return err } + pkgName := strings.ToLower(strings.ReplaceAll(name, "_", "")) + + err = writeTemplate( + "./"+pkgName+"/dialect_test.go", + tplDialectTest, + map[string]interface{}{ + "PkgName": pkgName, + }) + if err != nil { + return err + } + + entries, err := os.ReadDir(pkgName) + if err != nil { + return err + } + + for _, f := range entries { + if !strings.HasPrefix(f.Name(), "enum_") { + continue + } + + buf, err := os.ReadFile(filepath.Join(pkgName, f.Name())) + if err != nil { + return err + } + str := string(buf) + + if !strings.Contains(str, "MarshalText(") { + continue + } + + enumName := f.Name() + enumName = enumName[len("enum_"):] + enumName = enumName[:len(enumName)-len(".go")] + enumName = strings.ToUpper(enumName) + + err = writeTemplate( + "./"+pkgName+"/"+strings.ReplaceAll(f.Name(), ".go", "_test.go"), + tplEnumTest, + map[string]interface{}{ + "PkgName": pkgName, + "Name": enumName, + }) + if err != nil { + return err + } + } + fmt.Fprintf(os.Stderr, "\n") return nil } @@ -151,8 +224,6 @@ func run() error { return err } - var dialects []string //nolint:prealloc - for _, f := range files { if !strings.HasSuffix(f.Name, ".xml") { continue @@ -163,16 +234,12 @@ func run() error { if err != nil { return err } - - dialects = append(dialects, strings.ReplaceAll(strings.ToLower(name), "_", "")) } err = writeTemplate( "package_test.go", tplTest, - map[string]interface{}{ - "Dialects": dialects, - }) + map[string]interface{}{}) if err != nil { return err } diff --git a/pkg/conversion/conversion.go b/pkg/conversion/conversion.go index 71b45d3b2..d1283d4ed 100644 --- a/pkg/conversion/conversion.go +++ b/pkg/conversion/conversion.go @@ -29,8 +29,8 @@ var tplDialect = template.Must(template.New("").Parse( package {{ .PkgName }} import ( - "github.com/bluenviron/gomavlib/v3/pkg/message" - "github.com/bluenviron/gomavlib/v3/pkg/dialect" + "github.com/bluenviron/gomavlib/v3/pkg/message" + "github.com/bluenviron/gomavlib/v3/pkg/dialect" ) // Dialect contains the dialect definition. @@ -38,15 +38,15 @@ var Dialect = dial // dial is not exposed directly in order not to display it in godoc. var dial = &dialect.Dialect{ - Version: {{.Version}}, - Messages: []message.Message{ + Version: {{.Version}}, + Messages: []message.Message{ {{- range .Defs }} - // {{ .Name }} + // {{ .Name }} {{- range .Messages }} - &Message{{ .Name }}{}, + &Message{{ .Name }}{}, {{- end }} {{- end }} - }, + }, } `)) @@ -58,7 +58,7 @@ package {{ .PkgName }} {{- if .Link }} import ( - "github.com/bluenviron/gomavlib/v3/pkg/dialects/{{ .Enum.DefName }}" + "github.com/bluenviron/gomavlib/v3/pkg/dialects/{{ .Enum.DefName }}" ) {{- range .Enum.Description }} @@ -70,20 +70,20 @@ const ( {{- $en := .Enum }} {{- range .Enum.Values }} {{- range .Description }} - // {{ . }} + // {{ . }} {{- end }} - {{ .Name }} {{ $en.Name }} = {{ $en.DefName }}.{{ .Name }} + {{ .Name }} {{ $en.Name }} = {{ $en.DefName }}.{{ .Name }} {{- end }} ) {{- else }} import ( - "strconv" + "strconv" {{- if .Enum.Bitmask }} - "strings" + "strings" {{- end }} - "fmt" + "fmt" ) {{- range .Enum.Description }} @@ -95,77 +95,77 @@ const ( {{- $pn := .Enum.Name }} {{- range .Enum.Values }} {{- range .Description }} - // {{ . }} + // {{ . }} {{- end }} - {{ .Name }} {{ $pn }} = {{ .Value }} + {{ .Name }} {{ $pn }} = {{ .Value }} {{- end }} ) var labels_{{ .Enum.Name }} = map[{{ .Enum.Name }}]string{ {{- range .Enum.Values }} - {{ .Name }}: "{{ .Name }}", + {{ .Name }}: "{{ .Name }}", {{- end }} } var values_{{ .Enum.Name }} = map[string]{{ .Enum.Name }}{ {{- range .Enum.Values }} - "{{ .Name }}": {{ .Name }}, + "{{ .Name }}": {{ .Name }}, {{- end }} } // MarshalText implements the encoding.TextMarshaler interface. func (e {{ .Enum.Name }}) MarshalText() ([]byte, error) { {{- if .Enum.Bitmask }} - if e == 0 { - return []byte("0"), nil - } - var names []string - for i := 0; i < {{ len .Enum.Values }}; i++ { - mask := {{ .Enum.Name }}(1 << i) - if e&mask == mask { - names = append(names, labels_{{ .Enum.Name }}[mask]) - } - } - return []byte(strings.Join(names, " | ")), nil + if e == 0 { + return []byte("0"), nil + } + var names []string + for i := 0; i < {{ len .Enum.Values }}; i++ { + mask := {{ .Enum.Name }}(1 << i) + if e&mask == mask { + names = append(names, labels_{{ .Enum.Name }}[mask]) + } + } + return []byte(strings.Join(names, " | ")), nil {{- else }} - if name, ok := labels_{{ .Enum.Name }}[e]; ok { - return []byte(name), nil - } - return []byte(strconv.Itoa(int(e))), nil + if name, ok := labels_{{ .Enum.Name }}[e]; ok { + return []byte(name), nil + } + return []byte(strconv.Itoa(int(e))), nil {{- end }} } // UnmarshalText implements the encoding.TextUnmarshaler interface. func (e *{{ .Enum.Name }}) UnmarshalText(text []byte) error { {{- if .Enum.Bitmask }} - labels := strings.Split(string(text), " | ") - var mask {{ .Enum.Name }} - for _, label := range labels { - if value, ok := values_{{ .Enum.Name }}[label]; ok { - mask |= value - } else if value, err := strconv.Atoi(label); err == nil { - mask |= {{ .Enum.Name }}(value) - } else { - return fmt.Errorf("invalid label '%s'", label) - } - } + labels := strings.Split(string(text), " | ") + var mask {{ .Enum.Name }} + for _, label := range labels { + if value, ok := values_{{ .Enum.Name }}[label]; ok { + mask |= value + } else if value, err := strconv.Atoi(label); err == nil { + mask |= {{ .Enum.Name }}(value) + } else { + return fmt.Errorf("invalid label '%s'", label) + } + } *e = mask {{- else }} - if value, ok := values_{{ .Enum.Name }}[string(text)]; ok { - *e = value - } else if value, err := strconv.Atoi(string(text)); err == nil { - *e = {{ .Enum.Name }}(value) - } else { - return fmt.Errorf("invalid label '%s'", text) - } + if value, ok := values_{{ .Enum.Name }}[string(text)]; ok { + *e = value + } else if value, err := strconv.Atoi(string(text)); err == nil { + *e = {{ .Enum.Name }}(value) + } else { + return fmt.Errorf("invalid label '%s'", text) + } {{- end }} - return nil + return nil } // String implements the fmt.Stringer interface. func (e {{ .Enum.Name }}) String() string { - val, _ := e.MarshalText() - return string(val) + val, _ := e.MarshalText() + return string(val) } {{- end }} `)) @@ -178,7 +178,7 @@ package {{ .PkgName }} {{- if .Link }} import ( - "github.com/bluenviron/gomavlib/v3/pkg/dialects/{{ .Msg.DefName }}" + "github.com/bluenviron/gomavlib/v3/pkg/dialects/{{ .Msg.DefName }}" ) {{- range .Msg.Description }} @@ -194,15 +194,15 @@ type Message{{ .Msg.Name }} = {{ .Msg.DefName }}.Message{{ .Msg.Name }} type Message{{ .Msg.Name }} struct { {{- range .Msg.Fields }} {{- range .Description }} - // {{ . }} + // {{ . }} {{- end }} - {{ .Line }} + {{ .Line }} {{- end }} } // GetID implements the message.Message interface. func (*Message{{ .Msg.Name }}) GetID() uint32 { - return {{ .Msg.ID }} + return {{ .Msg.ID }} } {{- end }} diff --git a/pkg/conversion/conversion_test.go b/pkg/conversion/conversion_test.go index 0a929cb5d..a4c5f8434 100644 --- a/pkg/conversion/conversion_test.go +++ b/pkg/conversion/conversion_test.go @@ -57,19 +57,19 @@ var testMessageGo = `//autogenerated:yes package testdialect // Detected anomaly info measured by onboard sensors and actuators. type MessageAMessage struct { - // a test uint8 - TestUint8 A_TYPE ` + "`" + `mavenum:"uint8"` + "`" + ` - // a test string - TestString string ` + "`" + `mavlen:"16" mavname:"Test_string"` + "`" + ` - // a test array - TestArray [4]uint32 - // a test extension - MissionType MAV_MISSION_TYPE ` + "`" + `mavenum:"uint8" mavext:"true"` + "`" + ` + // a test uint8 + TestUint8 A_TYPE ` + "`" + `mavenum:"uint8"` + "`" + ` + // a test string + TestString string ` + "`" + `mavlen:"16" mavname:"Test_string"` + "`" + ` + // a test array + TestArray [4]uint32 + // a test extension + MissionType MAV_MISSION_TYPE ` + "`" + `mavenum:"uint8" mavext:"true"` + "`" + ` } // GetID implements the message.Message interface. func (*MessageAMessage) GetID() uint32 { - return 43000 + return 43000 } ` @@ -78,89 +78,89 @@ var testEnumGo = `//autogenerated:yes package testdialect import ( - "strconv" - "fmt" + "strconv" + "fmt" ) // Detected Anomaly Types. type A_TYPE uint64 const ( - // A. - A A_TYPE = 0 - // B. - B A_TYPE = 1 - // C. - C A_TYPE = 2 - // D. - D A_TYPE = 3 - // E - E A_TYPE = 4 - BIT0 A_TYPE = 1 - BIT4 A_TYPE = 16 - BIT8 A_TYPE = 256 - BIT16 A_TYPE = 65536 - BIT60 A_TYPE = 1152921504606846976 - BIT61 A_TYPE = 2305843009213693952 - BIT62 A_TYPE = 4611686018427387904 - BIT63 A_TYPE = 9223372036854775808 + // A. + A A_TYPE = 0 + // B. + B A_TYPE = 1 + // C. + C A_TYPE = 2 + // D. + D A_TYPE = 3 + // E + E A_TYPE = 4 + BIT0 A_TYPE = 1 + BIT4 A_TYPE = 16 + BIT8 A_TYPE = 256 + BIT16 A_TYPE = 65536 + BIT60 A_TYPE = 1152921504606846976 + BIT61 A_TYPE = 2305843009213693952 + BIT62 A_TYPE = 4611686018427387904 + BIT63 A_TYPE = 9223372036854775808 ) var labels_A_TYPE = map[A_TYPE]string{ - A: "A", - B: "B", - C: "C", - D: "D", - E: "E", - BIT0: "BIT0", - BIT4: "BIT4", - BIT8: "BIT8", - BIT16: "BIT16", - BIT60: "BIT60", - BIT61: "BIT61", - BIT62: "BIT62", - BIT63: "BIT63", + A: "A", + B: "B", + C: "C", + D: "D", + E: "E", + BIT0: "BIT0", + BIT4: "BIT4", + BIT8: "BIT8", + BIT16: "BIT16", + BIT60: "BIT60", + BIT61: "BIT61", + BIT62: "BIT62", + BIT63: "BIT63", } var values_A_TYPE = map[string]A_TYPE{ - "A": A, - "B": B, - "C": C, - "D": D, - "E": E, - "BIT0": BIT0, - "BIT4": BIT4, - "BIT8": BIT8, - "BIT16": BIT16, - "BIT60": BIT60, - "BIT61": BIT61, - "BIT62": BIT62, - "BIT63": BIT63, + "A": A, + "B": B, + "C": C, + "D": D, + "E": E, + "BIT0": BIT0, + "BIT4": BIT4, + "BIT8": BIT8, + "BIT16": BIT16, + "BIT60": BIT60, + "BIT61": BIT61, + "BIT62": BIT62, + "BIT63": BIT63, } // MarshalText implements the encoding.TextMarshaler interface. func (e A_TYPE) MarshalText() ([]byte, error) { - if name, ok := labels_A_TYPE[e]; ok { - return []byte(name), nil - } - return []byte(strconv.Itoa(int(e))), nil + if name, ok := labels_A_TYPE[e]; ok { + return []byte(name), nil + } + return []byte(strconv.Itoa(int(e))), nil } // UnmarshalText implements the encoding.TextUnmarshaler interface. func (e *A_TYPE) UnmarshalText(text []byte) error { - if value, ok := values_A_TYPE[string(text)]; ok { - *e = value - } else if value, err := strconv.Atoi(string(text)); err == nil { - *e = A_TYPE(value) - } else { - return fmt.Errorf("invalid label '%s'", text) - } - return nil + if value, ok := values_A_TYPE[string(text)]; ok { + *e = value + } else if value, err := strconv.Atoi(string(text)); err == nil { + *e = A_TYPE(value) + } else { + return fmt.Errorf("invalid label '%s'", text) + } + return nil } // String implements the fmt.Stringer interface. func (e A_TYPE) String() string { - val, _ := e.MarshalText() - return string(val) + val, _ := e.MarshalText() + return string(val) } ` diff --git a/pkg/dialects/all/dialect_test.go b/pkg/dialects/all/dialect_test.go new file mode 100644 index 000000000..3389fae99 --- /dev/null +++ b/pkg/dialects/all/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package all diff --git a/pkg/dialects/ardupilotmega/dialect_test.go b/pkg/dialects/ardupilotmega/dialect_test.go new file mode 100644 index 000000000..c16b115a9 --- /dev/null +++ b/pkg/dialects/ardupilotmega/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package ardupilotmega diff --git a/pkg/dialects/asluav/dialect_test.go b/pkg/dialects/asluav/dialect_test.go new file mode 100644 index 000000000..f10b97c65 --- /dev/null +++ b/pkg/dialects/asluav/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package asluav diff --git a/pkg/dialects/avssuas/dialect_test.go b/pkg/dialects/avssuas/dialect_test.go new file mode 100644 index 000000000..5b9508026 --- /dev/null +++ b/pkg/dialects/avssuas/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package avssuas diff --git a/pkg/dialects/common/dialect_test.go b/pkg/dialects/common/dialect_test.go new file mode 100644 index 000000000..f4c015b4a --- /dev/null +++ b/pkg/dialects/common/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package common diff --git a/pkg/dialects/csairlink/dialect_test.go b/pkg/dialects/csairlink/dialect_test.go new file mode 100644 index 000000000..0b00e425b --- /dev/null +++ b/pkg/dialects/csairlink/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package csairlink diff --git a/pkg/dialects/cubepilot/dialect_test.go b/pkg/dialects/cubepilot/dialect_test.go new file mode 100644 index 000000000..604c346f7 --- /dev/null +++ b/pkg/dialects/cubepilot/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package cubepilot diff --git a/pkg/dialects/development/dialect_test.go b/pkg/dialects/development/dialect_test.go new file mode 100644 index 000000000..635e83b93 --- /dev/null +++ b/pkg/dialects/development/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package development diff --git a/pkg/dialects/icarous/dialect_test.go b/pkg/dialects/icarous/dialect_test.go new file mode 100644 index 000000000..490f5a639 --- /dev/null +++ b/pkg/dialects/icarous/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package icarous diff --git a/pkg/dialects/matrixpilot/dialect_test.go b/pkg/dialects/matrixpilot/dialect_test.go new file mode 100644 index 000000000..07af1bc88 --- /dev/null +++ b/pkg/dialects/matrixpilot/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package matrixpilot diff --git a/pkg/dialects/minimal/dialect_test.go b/pkg/dialects/minimal/dialect_test.go new file mode 100644 index 000000000..a3a425119 --- /dev/null +++ b/pkg/dialects/minimal/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package minimal diff --git a/pkg/dialects/paparazzi/dialect_test.go b/pkg/dialects/paparazzi/dialect_test.go new file mode 100644 index 000000000..48f0a70df --- /dev/null +++ b/pkg/dialects/paparazzi/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package paparazzi diff --git a/pkg/dialects/pythonarraytest/dialect_test.go b/pkg/dialects/pythonarraytest/dialect_test.go new file mode 100644 index 000000000..7054e1ff1 --- /dev/null +++ b/pkg/dialects/pythonarraytest/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package pythonarraytest diff --git a/pkg/dialects/standard/dialect_test.go b/pkg/dialects/standard/dialect_test.go new file mode 100644 index 000000000..18b3bd0e9 --- /dev/null +++ b/pkg/dialects/standard/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package standard diff --git a/pkg/dialects/storm32/dialect_test.go b/pkg/dialects/storm32/dialect_test.go new file mode 100644 index 000000000..d28f30697 --- /dev/null +++ b/pkg/dialects/storm32/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package storm32 diff --git a/pkg/dialects/test/dialect_test.go b/pkg/dialects/test/dialect_test.go new file mode 100644 index 000000000..f781401e4 --- /dev/null +++ b/pkg/dialects/test/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package test diff --git a/pkg/dialects/ualberta/dialect_test.go b/pkg/dialects/ualberta/dialect_test.go new file mode 100644 index 000000000..20dcc6ae2 --- /dev/null +++ b/pkg/dialects/ualberta/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package ualberta diff --git a/pkg/dialects/uavionix/dialect_test.go b/pkg/dialects/uavionix/dialect_test.go new file mode 100644 index 000000000..d28b03a5f --- /dev/null +++ b/pkg/dialects/uavionix/dialect_test.go @@ -0,0 +1,3 @@ +//autogenerated:yes +//nolint:revive +package uavionix diff --git a/pkg/frame/reader_test.go b/pkg/frame/reader_test.go index 5edc5f153..cdd3529de 100644 --- a/pkg/frame/reader_test.go +++ b/pkg/frame/reader_test.go @@ -85,13 +85,16 @@ func (*MessageOpticalFlow) GetID() uint32 { } var testDialectRW = func() *dialect.ReadWriter { - d := &dialect.Dialect{3, []message.Message{ //nolint:govet - &MessageTest5{}, - &MessageTest6{}, - &MessageTest9{}, - &MessageHeartbeat{}, - &MessageOpticalFlow{}, - }} + d := &dialect.Dialect{ + Version: 3, + Messages: []message.Message{ + &MessageTest5{}, + &MessageTest6{}, + &MessageTest9{}, + &MessageHeartbeat{}, + &MessageOpticalFlow{}, + }, + } de, err := dialect.NewReadWriter(d) if err != nil { panic(err) @@ -130,9 +133,9 @@ var casesReadWrite = []struct { SequenceNumber: 0x27, SystemID: 0x01, ComponentID: 0x02, - Message: &message.MessageRaw{ //nolint:govet - 8, - []byte("\x10\x10\x10\x10\x10"), + Message: &message.MessageRaw{ + ID: 8, + Payload: []byte("\x10\x10\x10\x10\x10"), }, Checksum: 0xc7fa, }, @@ -164,9 +167,9 @@ var casesReadWrite = []struct { SequenceNumber: 3, SystemID: 4, ComponentID: 5, - Message: &message.MessageRaw{ //nolint:govet - 4, - nil, + Message: &message.MessageRaw{ + ID: 4, + Payload: nil, }, Checksum: 0x0ab7, }, @@ -182,9 +185,9 @@ var casesReadWrite = []struct { SequenceNumber: 0x8F, SystemID: 0x01, ComponentID: 0x02, - Message: &message.MessageRaw{ //nolint:govet - 0x0607, - []byte("\x10\x10\x10\x10\x10"), + Message: &message.MessageRaw{ + ID: 0x0607, + Payload: []byte("\x10\x10\x10\x10\x10"), }, Checksum: 0x0349, }, diff --git a/pkg/timednetconn/conn_test.go b/pkg/timednetconn/conn_test.go new file mode 100644 index 000000000..698157b6a --- /dev/null +++ b/pkg/timednetconn/conn_test.go @@ -0,0 +1,74 @@ +package timednetconn + +import ( + "net" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +type fakeConn struct { + readDeadlineDone chan struct{} + writeDeadlineDone chan struct{} + closeDone chan struct{} +} + +func (fc *fakeConn) Read(_ []byte) (n int, err error) { + return 10, nil +} + +func (fc *fakeConn) Write(_ []byte) (n int, err error) { + return 10, nil +} + +func (fc *fakeConn) Close() error { + close(fc.closeDone) + return nil +} + +func (fc *fakeConn) LocalAddr() net.Addr { + return nil +} + +func (fc *fakeConn) RemoteAddr() net.Addr { + return nil +} + +func (fc *fakeConn) SetDeadline(_ time.Time) error { + return nil +} + +func (fc *fakeConn) SetReadDeadline(_ time.Time) error { + close(fc.readDeadlineDone) + return nil +} + +func (fc *fakeConn) SetWriteDeadline(_ time.Time) error { + close(fc.writeDeadlineDone) + return nil +} + +func TestConn(t *testing.T) { + fc := &fakeConn{ + readDeadlineDone: make(chan struct{}), + writeDeadlineDone: make(chan struct{}), + closeDone: make(chan struct{}), + } + + conn := New(10*time.Second, 10*time.Second, fc) + + n, err := conn.Read(nil) + require.NoError(t, err) + require.Equal(t, 10, n) + <-fc.readDeadlineDone + + n, err = conn.Write(nil) + require.NoError(t, err) + require.Equal(t, 10, n) + <-fc.writeDeadlineDone + + err = conn.Close() + require.NoError(t, err) + <-fc.closeDone +}