diff --git a/generate/generate_test.go b/generate/generate_test.go index 1acac06..5b5a49d 100644 --- a/generate/generate_test.go +++ b/generate/generate_test.go @@ -1,151 +1,15 @@ package generate // import "fmt" -import "strings" import "testing" -import "git.tebibyte.media/sashakoshka/goparse" -var testGenerateCorrect = -`package protocol +// TODO: once everything has been ironed out, test that the public API of the +// generator is equal to something specific -/* # Do not edit this package by hand! - * - * This file was automatically generated by the Holanet PDL compiler. The - * source file is located at input.pdl - * Please edit that file instead, and re-compile it to this location. - * - * HOPP, TAPE, METADAPT, PDL/0 (c) 2025 holanet.xyz - */ +var exampleProtocol = defaultProtocol() -import "git.tebibyte.media/sashakoshka/hopp/tape" - -// Table is a KTV table with an undefined schema. -type Table map[uint16] any - -// Message is any message that can be sent along this protocol. -type Message interface { - tape.Encodable - tape.Decodable - - // Method returns the method code of the message. - Method() uint16 -} - -// User represents the protocol data type User. -type User struct { - Name string - Bio string - Followers uint32 -} - -// EncodeValue encodes the value of this type without the tag. The value is -// encoded according to the parameters specified by the tag, if possible. -func (this *User) EncodeValue(encoder *tape.Encoder) (n int, err error) { - nn, err := tape.WriteTableHeader(2) - n += nn; if err != nil { return n, err } - nn, err := encoder.WriteUint16(0x0000) - n += nn; if err != nil { return n, err } - nn, err := tape.WriteString(encoder, this.Name) - n += nn; if err != nil { return n, err } - nn, err := encoder.WriteUint16(0x0001) - n += nn; if err != nil { return n, err } - nn, err := tape.WriteString(encoder, this.Bio) - n += nn; if err != nil { return n, err } - return n, nil -} - -// Decode replaces the data in this User with information from the decoder. -func (this *User) Decode(decoder *tape.Decoder) (n int, err error) { - pull, nn, err := tape.ReadTableHeader(decoder) - n += nn; if err != nil { return n, err } - - for { - key, tag, end, nn, err := pull() - n += nn; if err != nil { return n, err } - if end { break } - - switch key { - case 0x0000: - value, nn, err := tape.ReadString(decoder) - n += nn; if err != nil { return n, err } - this.Name = value - case 0x0001: - value, nn, err := tape.ReadString(decoder) - n += nn; if err != nil { return n, err } - this.Bio = value - } - } - - return n, nil -} - -// MessageConnect represents the protocol message M0000 Connect. -type MessageConnect struct { - Name string - Password string -} - -// Method returns the method code, M0000. -func (this *MessageConnect) Method() uint16 { - return 0x0000 -} - -// Encode encodes the message to the encoder. -func (this *MessageConnect) Encode(encoder *tape.Encoder) (n int, err error) { - nn, err := tape.WriteTableHeader(2) - n += nn; if err != nil { return n, err } - nn, err := encoder.WriteUint16(0x0000) - n += nn; if err != nil { return n, err } - nn, err := tape.WriteString(encoder, this.Name) - n += nn; if err != nil { return n, err } - nn, err := encoder.WriteUint16(0x0001) - n += nn; if err != nil { return n, err } - nn, err := tape.WriteString(encoder, this.Password) - n += nn; if err != nil { return n, err } - return n, nil -} - -// Decode replaces the data in this message with information from the decoder. -func (this *MessageConnect) Decode(decoder *tape.Decoder) (n int, err error) { - pull, nn, err := tape.ReadTableHeader(decoder) - n += nn; if err != nil { return n, err } - - for { - key, tag, end, nn, err := pull() - n += nn; if err != nil { return n, err } - if end { break } - - switch key { - case 0x0000: - value, nn, err := tape.ReadString(decoder) - n += nn; if err != nil { return n, err } - this.Name = value - case 0x0001: - value, nn, err := tape.ReadString(decoder) - n += nn; if err != nil { return n, err } - this.Password = value - } - } - - return n, nil -} - -// MessageUserList represents the protocol message M0001 UserList. -type MessageUserList struct { - Users []User -} - -// Method returns the method code, M0001. -func (this *MessageUserList) Method() uint16 { - return 0x0001 -} - -// TODO methods -` - -func TestGenerate(test *testing.T) { - protocol := defaultProtocol() - protocol.Messages[0x0000] = Message { +func init() { + exampleProtocol.Messages[0x0000] = Message { Name: "Connect", Type: TypeTableDefined { Fields: map[uint16] Field { @@ -154,7 +18,7 @@ func TestGenerate(test *testing.T) { }, }, } - protocol.Messages[0x0001] = Message { + exampleProtocol.Messages[0x0001] = Message { Name: "UserList", Type: TypeTableDefined { Fields: map[uint16] Field { @@ -162,59 +26,7 @@ func TestGenerate(test *testing.T) { }, }, } - protocol.Types["User"] = TypeTableDefined { - Fields: map[uint16] Field { - 0x0000: Field { Name: "Name", Type: TypeString { } }, - 0x0001: Field { Name: "Bio", Type: TypeString { } }, - 0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } }, - }, - } - - correct := testGenerateCorrect - - builder := strings.Builder { } - generator := Generator { Output: &builder } - /* TODO test n: */ _, err := generator.Generate(&protocol) - if err != nil { test.Fatal(parse.Format(err)) } - got := builder.String() - - test.Log("CORRECT:") - test.Log(correct) - test.Log("GOT:") - test.Log(got) - - if correct != got { - test.Error("not equal") - for index := range min(len(correct), len(got)) { - if correct[index] == got[index] { continue } - test.Log("C:", correct[max(0, index - 8):min(len(correct), index + 8)]) - test.Log("G:", got[max(0, index - 8):min(len(got), index + 8)]) - break - } - test.FailNow() - } -} - -func TestGenerateRun(test *testing.T) { - protocol := defaultProtocol() - protocol.Messages[0x0000] = Message { - Name: "Connect", - Type: TypeTableDefined { - Fields: map[uint16] Field { - 0x0000: Field { Name: "Name", Type: TypeString { } }, - 0x0001: Field { Name: "Password", Type: TypeString { } }, - }, - }, - } - protocol.Messages[0x0001] = Message { - Name: "UserList", - Type: TypeTableDefined { - Fields: map[uint16] Field { - 0x0000: Field { Name: "Users", Type: TypeArray { Element: TypeNamed { Name: "User" } } }, - }, - }, - } - protocol.Messages[0x0002] = Message { + exampleProtocol.Messages[0x0002] = Message { Name: "Pulse", Type: TypeTableDefined { Fields: map[uint16] Field { @@ -226,11 +38,11 @@ func TestGenerateRun(test *testing.T) { }, }, } - protocol.Messages[0x0003] = Message { + exampleProtocol.Messages[0x0003] = Message { Name: "NestedArray", Type: TypeArray { Element: TypeArray { Element: TypeInt { Bits: 8 } } }, } - protocol.Messages[0x0004] = Message { + exampleProtocol.Messages[0x0004] = Message { Name: "Integers", Type: TypeTableDefined { Fields: map[uint16] Field { @@ -250,14 +62,17 @@ func TestGenerateRun(test *testing.T) { }, }, } - protocol.Types["User"] = TypeTableDefined { + exampleProtocol.Types["User"] = TypeTableDefined { Fields: map[uint16] Field { 0x0000: Field { Name: "Name", Type: TypeString { } }, 0x0001: Field { Name: "Bio", Type: TypeString { } }, 0x0002: Field { Name: "Followers", Type: TypeInt { Bits: 32 } }, }, } - testGenerateRun(test, &protocol, ` +} + +func TestGenerateRun(test *testing.T) { + testGenerateRun(test, &exampleProtocol, ` // imports `, ` // test case