transaction: Add support for using raw binary pointers conversation handler

This requires the allocating function to provide a binary pointer that
will be free'd by the conversation handlers finalizers.

This is for a more advanced usage scenario where the binary conversion
may be handled manually.
This commit is contained in:
Marco Trevisan (Treviño)
2023-11-07 14:22:43 +02:00
parent 0143d11445
commit 89c1e430c1
4 changed files with 196 additions and 0 deletions

View File

@@ -938,6 +938,145 @@ func testMockModuleTransaction(t *testing.T, mt *moduleTransaction) {
return mt.startConvImpl(mock, NewStringConvRequest(TextInfo, "prompt"))
},
},
"StartConv-Binary-with-PointerConvFunc": {
expectedValue: []byte{0x01, 0x02, 0x03, 0x05, 0x00, 0x95},
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
bytes, _ := testBinaryDataDecoder(ptr)
expectedBinary := []byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From bytes pointer.")
if !reflect.DeepEqual(bytes, expectedBinary) {
return nil,
fmt.Errorf("%w: data mismatch %#v vs %#v", ErrConv, bytes, expectedBinary)
}
return allocateCBytes(testBinaryDataEncoder([]byte{
0x01, 0x02, 0x03, 0x05, 0x00, 0x95})), nil
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
bytes := testBinaryDataEncoder([]byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From bytes pointer."))
data, err := mt.startConvImpl(mock, NewBinaryConvRequestFromBytes(bytes))
if err != nil {
return data, err
}
resp, _ := data.(BinaryConvResponse)
return resp.Decode(testBinaryDataDecoder)
},
},
"StartConv-Binary-with-PointerConvFunc-and-allocated-data": {
expectedValue: []byte{0x01, 0x02, 0x03, 0x05, 0x00, 0x95},
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
bytes, _ := testBinaryDataDecoder(ptr)
expectedBinary := []byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From pointer...")
if !reflect.DeepEqual(bytes, expectedBinary) {
return nil,
fmt.Errorf("%w: data mismatch %#v vs %#v", ErrConv, bytes, expectedBinary)
}
return allocateCBytes(testBinaryDataEncoder([]byte{
0x01, 0x02, 0x03, 0x05, 0x00, 0x95})), nil
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
bytes := testBinaryDataEncoder([]byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From pointer..."))
data, err := mt.startConvImpl(mock,
NewBinaryConvRequest(allocateCBytes(bytes), binaryPointerCBytesFinalizer))
if err != nil {
return data, err
}
resp, _ := data.(BinaryConvResponse)
return resp.Decode(testBinaryDataDecoder)
},
},
"StartConv-Binary-with-PointerConvFunc-and-allocated-data-erroring": {
expectedValue: nil,
expectedError: ErrConv,
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
bytes, _ := testBinaryDataDecoder(ptr)
expectedBinary := []byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From pointer...")
if !reflect.DeepEqual(bytes, expectedBinary) {
return nil,
fmt.Errorf("%w: data mismatch %#v vs %#v", ErrConv, bytes, expectedBinary)
}
return allocateCBytes(testBinaryDataEncoder([]byte{
0x01, 0x02, 0x03, 0x05, 0x00, 0x95})), ErrConv
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
bytes := testBinaryDataEncoder([]byte(
"\x00This is a binary data request\xC5\x00\xffYes it is! From pointer..."))
data, err := mt.startConvImpl(mock,
NewBinaryConvRequest(allocateCBytes(bytes), binaryPointerCBytesFinalizer))
if err != nil {
return data, err
}
resp, _ := data.(BinaryConvResponse)
return resp.Decode(testBinaryDataDecoder)
},
},
"StartConv-Binary-with-PointerConvFunc-empty": {
expectedValue: []byte{},
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
bytes, _ := testBinaryDataDecoder(ptr)
expectedBinary := []byte(
"\x00This is an empty binary data request\xC5\x00\xffYes it is!")
if !reflect.DeepEqual(bytes, expectedBinary) {
return nil,
fmt.Errorf("%w: data mismatch %#v vs %#v", ErrConv, bytes, expectedBinary)
}
return allocateCBytes(testBinaryDataEncoder([]byte{})), nil
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
bytes := testBinaryDataEncoder([]byte(
"\x00This is an empty binary data request\xC5\x00\xffYes it is!"))
data, err := mt.startConvImpl(mock, NewBinaryConvRequestFromBytes(bytes))
if err != nil {
return data, err
}
resp, _ := data.(BinaryConvResponse)
return resp.Decode(testBinaryDataDecoder)
},
},
"StartConv-Binary-with-PointerConvFunc-nil": {
expectedValue: []byte(nil),
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
bytes, _ := testBinaryDataDecoder(ptr)
expectedBinary := []byte(
"\x00This is a nil binary data request\xC5\x00\xffYes it is!")
if !reflect.DeepEqual(bytes, expectedBinary) {
return nil,
fmt.Errorf("%w: data mismatch %#v vs %#v", ErrConv, bytes, expectedBinary)
}
return nil, nil
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
bytes := testBinaryDataEncoder([]byte(
"\x00This is a nil binary data request\xC5\x00\xffYes it is!"))
data, err := mt.startConvImpl(mock, NewBinaryConvRequestFromBytes(bytes))
if err != nil {
return data, err
}
resp, _ := data.(BinaryConvResponse)
return resp.Decode(testBinaryDataDecoder)
},
},
"StartConv-Binary-with-PointerConvFunc-error": {
expectedError: ErrConv,
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
return nil, errors.New("got an error")
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
return mt.startConvImpl(mock, NewBinaryConvRequestFromBytes([]byte{}))
},
},
"StartConv-String-with-ConvPointerBinaryFunc": {
expectedError: ErrConv,
conversationHandler: BinaryPointerConversationFunc(func(ptr BinaryPointer) (BinaryPointer, error) {
return nil, nil
}),
testFunc: func(mock *mockModuleTransaction) (any, error) {
return mt.startConvImpl(mock, NewStringConvRequest(TextInfo, "prompt"))
},
},
}
for name, tc := range tests {