standardize processor instance creation in tests

This commit is contained in:
Joel Wetzell
2026-02-09 22:09:48 -06:00
parent f028634401
commit a408e281a3
14 changed files with 599 additions and 191 deletions

View File

@@ -71,12 +71,15 @@ func TestGoodArtnetPacketFilter(t *testing.T) {
tests := []struct {
name string
params map[string]any
payload any
opCode uint16
expected artnet.ArtNetPacket
}{
{
name: "tiemcode packet with matching opCode",
params: map[string]any{
"opCode": float64(artnet.OpTimeCode),
},
payload: &artnet.ArtTimeCode{
ID: []byte{'A', 'r', 't', '-', 'N', 'e', 't', 0x00},
OpCode: artnet.OpTimeCode,
@@ -90,7 +93,6 @@ func TestGoodArtnetPacketFilter(t *testing.T) {
Hours: 0,
Type: 0,
},
opCode: artnet.OpTimeCode,
expected: &artnet.ArtTimeCode{
ID: []byte{'A', 'r', 't', '-', 'N', 'e', 't', 0x00},
OpCode: artnet.OpTimeCode,
@@ -106,7 +108,10 @@ func TestGoodArtnetPacketFilter(t *testing.T) {
},
},
{
name: "tiemcode packet with mismatching opCode",
name: "timecode packet with mismatching opCode",
params: map[string]any{
"opCode": float64(artnet.OpDmx),
},
payload: &artnet.ArtTimeCode{
ID: []byte{'A', 'r', 't', '-', 'N', 'e', 't', 0x00},
OpCode: artnet.OpTimeCode,
@@ -120,17 +125,27 @@ func TestGoodArtnetPacketFilter(t *testing.T) {
Hours: 0,
Type: 0,
},
opCode: artnet.OpDmx,
expected: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
artnetPacketFilter := processor.ArtNetPacketFilter{
OpCode: test.opCode,
registration, ok := processor.ProcessorRegistry["artnet.packet.filter"]
if !ok {
t.Fatalf("artnet.packet.filter processor not registered")
}
got, err := artnetPacketFilter.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "artnet.packet.filter",
Params: test.params,
})
if err != nil {
t.Fatalf("artnet.packet.filter failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("artnet.packet.filter failed: %s", err)
@@ -158,8 +173,8 @@ func TestGoodArtnetPacketFilter(t *testing.T) {
func TestBadArtnetPacketFilter(t *testing.T) {
tests := []struct {
name string
payload any
params map[string]any
payload any
errorString string
}{
{

View File

@@ -80,37 +80,55 @@ func TestFloatParseGoodConfig(t *testing.T) {
}
func TestGoodFloatParse(t *testing.T) {
floatParser := processor.FloatParse{}
tests := []struct {
processor processor.Processor
name string
payload any
bitSize int
expected float64
name string
params map[string]any
payload any
expected float64
}{
{
name: "positive number",
name: "positive number",
params: map[string]any{
"bitSize": 64.0,
},
payload: "12345.67",
bitSize: 64,
expected: 12345.67,
},
{
name: "negative number",
name: "negative number",
params: map[string]any{
"bitSize": 64.0,
},
payload: "-12345.67",
bitSize: 64,
expected: -12345.67,
},
{
name: "zero",
name: "zero",
params: map[string]any{
"bitSize": 64.0,
},
payload: "0",
bitSize: 64,
expected: 0,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := floatParser.Process(t.Context(), test.payload)
registration, ok := processor.ProcessorRegistry["float.parse"]
if !ok {
t.Fatalf("float.parse processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "float.parse",
Params: test.params,
})
if err != nil {
t.Fatalf("float.parse failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotFloat, ok := got.(float64)
if !ok {
@@ -128,38 +146,50 @@ func TestGoodFloatParse(t *testing.T) {
func TestBadFloatParse(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
params map[string]any
payload any
bitSize int
errorString string
}{
{
name: "non-string input",
name: "non-string input",
params: map[string]any{
"bitSize": 64.0,
},
payload: []byte{0x01},
bitSize: 64,
errorString: "float.parse processor only accepts a string",
},
{
name: "not float string",
name: "not float string",
params: map[string]any{
"bitSize": 64.0,
},
payload: "abcd",
bitSize: 64,
errorString: "strconv.ParseFloat: parsing \"abcd\": invalid syntax",
},
{
name: "bit size overflow",
name: "bit size overflow",
params: map[string]any{
"bitSize": 32.0,
},
payload: "1.79e+64",
bitSize: 32,
errorString: "strconv.ParseFloat: parsing \"1.79e+64\": value out of range",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
floatParser := processor.FloatParse{
BitSize: test.bitSize,
registration, ok := processor.ProcessorRegistry["float.parse"]
if !ok {
t.Fatalf("float.parse processor not registered")
}
got, err := floatParser.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "float.parse",
Params: test.params,
})
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("float.parse expected to fail but succeeded, got: %v", got)

View File

@@ -100,58 +100,75 @@ func TestIntParseGoodConfig(t *testing.T) {
func TestGoodIntParse(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
expected int64
base int
bitSize int
name string
params map[string]any
payload any
expected int64
}{
{
name: "positive number",
name: "positive number",
params: map[string]any{
"base": 10.0,
"bitSize": 64.0,
},
payload: "12345",
expected: 12345,
base: 10,
bitSize: 64,
},
{
name: "negative number",
name: "negative number",
params: map[string]any{
"base": 10.0,
"bitSize": 64.0,
},
payload: "-12345",
expected: -12345,
base: 10,
bitSize: 64,
},
{
name: "zero",
name: "zero",
params: map[string]any{
"base": 10.0,
"bitSize": 64.0,
},
payload: "0",
expected: 0,
base: 10,
bitSize: 64,
},
{
name: "binary",
name: "binary",
params: map[string]any{
"base": 2.0,
"bitSize": 64.0,
},
payload: "1010101",
expected: 85,
base: 2,
bitSize: 64,
},
{
name: "hex",
name: "hex",
params: map[string]any{
"base": 16.0,
"bitSize": 64.0,
},
payload: "15F",
expected: 351,
base: 16,
bitSize: 64,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
intParser := processor.IntParse{
Base: test.base,
BitSize: test.bitSize,
registration, ok := processor.ProcessorRegistry["int.parse"]
if !ok {
t.Fatalf("int.parse processor not registered")
}
got, err := intParser.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "int.parse",
Params: test.params,
})
if err != nil {
t.Fatalf("int.parse failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotInt, ok := got.(int64)
if !ok {
@@ -169,43 +186,53 @@ func TestGoodIntParse(t *testing.T) {
func TestBadIntParse(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
params map[string]any
payload any
base int
bitSize int
errorString string
}{
{
name: "non-string input",
name: "non-string input",
params: map[string]any{
"base": 10.0,
"bitSize": 64.0,
},
payload: []byte{0x01},
base: 10,
bitSize: 64,
errorString: "int.parse processor only accepts a string",
},
{
name: "not int string",
name: "not int string",
params: map[string]any{
"base": 10.0,
"bitSize": 64.0,
},
payload: "123.46",
base: 10,
bitSize: 64,
errorString: "strconv.ParseInt: parsing \"123.46\": invalid syntax",
},
{
name: "bit overflow",
name: "bit overflow",
params: map[string]any{
"base": 10.0,
"bitSize": 32.0,
},
payload: "12345678901234567890",
base: 10,
bitSize: 32,
errorString: "strconv.ParseInt: parsing \"12345678901234567890\": value out of range",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
intParser := processor.IntParse{
Base: test.base,
BitSize: test.bitSize,
registration, ok := processor.ProcessorRegistry["int.parse"]
if !ok {
t.Fatalf("int.parse processor not registered")
}
got, err := intParser.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "int.parse",
Params: test.params,
})
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("int.parse expected to fail but succeeded, got: %v", got)

View File

@@ -67,27 +67,37 @@ func TestIntRandomGoodConfig(t *testing.T) {
func TestGoodIntRandom(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
min int
max int
name string
payload any
params map[string]any
}{
{
name: "1-10",
name: "1-10",
params: map[string]any{
"min": 1.0,
"max": 10.0,
},
payload: "12345",
min: 1,
max: 10,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
intRandom := processor.IntRandom{
Min: test.min,
Max: test.max,
registration, ok := processor.ProcessorRegistry["int.random"]
if !ok {
t.Fatalf("int.random processor not registered")
}
got, err := intRandom.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "int.random",
Params: test.params,
})
if err != nil {
t.Fatalf("int.random failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotInt, ok := got.(int)
if !ok {
t.Fatalf("int.random returned a %T payload: %s", got, got)
@@ -95,8 +105,18 @@ func TestGoodIntRandom(t *testing.T) {
if err != nil {
t.Fatalf("int.random failed: %s", err)
}
if gotInt < test.min || gotInt > test.max {
t.Fatalf("int.random got %d, expected between %d and %d", gotInt, test.min, test.max)
minNum, ok := test.params["min"].(float64)
if !ok {
t.Fatalf("int.random test min param is not a number: %s", test.params["min"])
}
maxNum, ok := test.params["max"].(float64)
if !ok {
t.Fatalf("int.random test max param is not a number: %s", test.params["max"])
}
if gotInt < int(minNum) || gotInt > int(maxNum) {
t.Fatalf("int.random got %d, expected between %d and %d", gotInt, int(minNum), int(maxNum))
}
})
}

View File

@@ -1,10 +1,12 @@
package processor_test
import (
"slices"
"testing"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
"gitlab.com/gomidi/midi/v2"
)
func TestMIDIMessageEncodeFromRegistry(t *testing.T) {
@@ -25,3 +27,63 @@ func TestMIDIMessageEncodeFromRegistry(t *testing.T) {
t.Fatalf("midi.message.encode processor has wrong type: %s", processorInstance.Type())
}
}
func TestGoodMIDIMessageEncode(t *testing.T) {
midiMessageEncoder := processor.MIDIMessageEncode{}
tests := []struct {
name string
payload any
expected []byte
}{
{
name: "note on message",
payload: midi.NoteOn(1, 60, 127),
expected: []byte{0x91, 0x3c, 0x7f},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := midiMessageEncoder.Process(t.Context(), test.payload)
gotBytes, ok := got.([]byte)
if !ok {
t.Fatalf("midi.message.encode returned a %T payload: %s", got, got)
}
if err != nil {
t.Fatalf("midi.message.encode failed: %s", err)
}
if !slices.Equal(gotBytes, test.expected) {
t.Fatalf("midi.message.encode got %+v, expected %+v", got, test.expected)
}
})
}
}
func TestBadMIDIMessageEncode(t *testing.T) {
midiMessageEncoder := processor.MIDIMessageEncode{}
tests := []struct {
name string
payload any
errorString string
}{
{
name: "non-midi message input",
payload: []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f},
errorString: "midi.message.encode processor only accepts a midi.Message",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := midiMessageEncoder.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("midi.message.encode expected to fail but got payload: %s", got)
}
if err.Error() != test.errorString {
t.Fatalf("midi.message.encode got error '%s', expected '%s'", err.Error(), test.errorString)
}
})
}
}

View File

@@ -1,10 +1,12 @@
package processor_test
import (
"reflect"
"testing"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
"gitlab.com/gomidi/midi/v2"
)
func TestMIDIMessageFilterFromRegistry(t *testing.T) {
@@ -28,3 +30,128 @@ func TestMIDIMessageFilterFromRegistry(t *testing.T) {
t.Fatalf("midi.message.filter processor has wrong type: %s", processorInstance.Type())
}
}
func TestGoodMIDIMessageFilter(t *testing.T) {
tests := []struct {
name string
params map[string]any
payload midi.Message
expected midi.Message
}{
{
name: "matches pattern",
payload: midi.NoteOn(1, 60, 127),
params: map[string]any{"type": "NoteOn"},
expected: midi.NoteOn(1, 60, 127),
},
{
name: "does not match pattern",
payload: midi.NoteOn(1, 60, 127),
params: map[string]any{"type": "NoteOff"},
expected: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
registration, ok := processor.ProcessorRegistry["midi.message.filter"]
if !ok {
t.Fatalf("midi.message.filter processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "midi.message.filter",
Params: test.params,
})
if err != nil {
t.Fatalf("midi.message.filter failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("midi.message.filter failed: %s", err)
}
if test.expected == nil {
if got != nil {
t.Fatalf("midi.message.filter got %+v, expected nil", got)
}
return
}
gotMIDIMessage, ok := got.(midi.Message)
if !ok {
t.Fatalf("midi.message.filter returned a %T payload: %s", got, got)
}
if !reflect.DeepEqual(gotMIDIMessage, test.expected) {
t.Fatalf("midi.message.filter got %+v, expected %+v", gotMIDIMessage, test.expected)
}
})
}
}
func TestBadMIDIMessageFilter(t *testing.T) {
tests := []struct {
name string
params map[string]any
payload any
errorString string
}{
{
name: "no type param",
params: map[string]any{},
payload: midi.NoteOn(1, 60, 127),
errorString: "midi.message.filter requires a type parameter",
},
{
name: "non-string type param",
params: map[string]any{
"type": 123,
},
payload: "hello",
errorString: "midi.message.filter type must be a string",
},
{
name: "non-midi message input",
params: map[string]any{
"type": "NoteOn",
},
payload: []byte{0x68, 0x65, 0x6c, 0x6c, 0x6f},
errorString: "midi.message.filter processor only accepts a midi.Message",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
registration, ok := processor.ProcessorRegistry["midi.message.filter"]
if !ok {
t.Fatalf("midi.message.filter processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "midi.message.filter",
Params: test.params,
})
if err != nil {
if test.errorString != err.Error() {
t.Fatalf("midi.message.filter got error '%s', expected '%s'", err.Error(), test.errorString)
}
return
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("midi.message.filter expected to fail but got payload: %s", got)
}
if err.Error() != test.errorString {
t.Fatalf("midi.message.filter got error '%s', expected '%s'", err.Error(), test.errorString)
}
})
}
}

View File

@@ -3,7 +3,6 @@ package processor_test
import (
"testing"
"github.com/expr-lang/expr"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
)
@@ -83,14 +82,16 @@ func TestScriptExprBadConfigNonCompilingExpression(t *testing.T) {
func TestGoodScriptExpr(t *testing.T) {
tests := []struct {
program string
name string
params map[string]any
payload map[string]any
expected any
}{
{
program: "foo + bar",
name: "number",
name: "number",
params: map[string]any{
"expression": "foo + bar",
},
payload: map[string]any{
"foo": 1,
"bar": 1,
@@ -98,8 +99,10 @@ func TestGoodScriptExpr(t *testing.T) {
expected: 2,
},
{
program: "foo + bar",
name: "string",
name: "string",
params: map[string]any{
"expression": "foo + bar",
},
payload: map[string]any{
"foo": "1",
"bar": "1",
@@ -110,14 +113,21 @@ func TestGoodScriptExpr(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
program, err := expr.Compile(test.program)
if err != nil {
t.Fatalf("script.expr failed to compile program: %s", err)
registration, ok := processor.ProcessorRegistry["script.expr"]
if !ok {
t.Fatalf("script.expr processor not registered")
}
exprProcessor := &processor.ScriptExpr{Program: program}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "script.expr",
Params: test.params,
})
got, err := exprProcessor.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("script.expr failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("script.expr failed: %s", err)
@@ -133,14 +143,16 @@ func TestGoodScriptExpr(t *testing.T) {
func TestBadScriptExpr(t *testing.T) {
tests := []struct {
program string
name string
params map[string]any
payload map[string]any
errorString string
}{
{
name: "accessing missing field",
program: "foo + bar",
name: "accessing missing field",
params: map[string]any{
"expression": "foo + bar",
},
payload: map[string]any{
"foo": 1,
},
@@ -150,14 +162,17 @@ func TestBadScriptExpr(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
program, err := expr.Compile(test.program)
if err != nil {
t.Fatalf("script.expr failed to compile program: %s", err)
registration, ok := processor.ProcessorRegistry["script.expr"]
if !ok {
t.Fatalf("script.expr processor not registered")
}
exprProcessor := &processor.ScriptExpr{Program: program}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "script.expr",
Params: test.params,
})
got, err := exprProcessor.Process(t.Context(), test.payload)
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("script.expr expected to fail but succeeded, got: %v", got)

View File

@@ -79,40 +79,48 @@ func TestScriptJSBadConfigWrongProgramType(t *testing.T) {
func TestGoodScriptJS(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
expected any
name string
params map[string]any
payload any
expected any
}{
{
name: "number",
processor: &processor.ScriptJS{Program: `
payload = payload + 1
`},
params: map[string]any{
"program": `
payload = payload + 1
`,
},
payload: 1,
expected: 2,
},
{
name: "string",
processor: &processor.ScriptJS{Program: `
payload = payload + "1"
`},
params: map[string]any{
"program": `
payload = payload + "1"
`,
},
payload: "1",
expected: "11",
},
{
name: "object",
processor: &processor.ScriptJS{Program: `
payload = { key: payload }
`},
params: map[string]any{
"program": `
payload = { key: payload }
`,
},
payload: "1",
expected: map[string]any{"key": "1"},
},
{
name: "nil",
processor: &processor.ScriptJS{Program: `
payload = undefined
`},
params: map[string]any{
"program": `
payload = undefined
`,
},
payload: "1",
expected: nil,
},
@@ -120,7 +128,21 @@ func TestGoodScriptJS(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := test.processor.Process(t.Context(), test.payload)
registration, ok := processor.ProcessorRegistry["script.js"]
if !ok {
t.Fatalf("script.js processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "script.js",
Params: test.params,
})
if err != nil {
t.Fatalf("script.js failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("script.js process failed: %s", err)
@@ -151,13 +173,17 @@ func TestGoodScriptJS(t *testing.T) {
func TestBadScriptJS(t *testing.T) {
tests := []struct {
name string
processor processor.Processor
params map[string]any
payload any
errorString string
}{
{
name: "accessing not defined variable",
processor: &processor.ScriptJS{Program: `paylod = foo`},
name: "accessing not defined variable",
params: map[string]any{
"program": `
paylod = foo
`,
},
payload: 0,
errorString: "ReferenceError: 'foo' is not defined",
},
@@ -165,7 +191,17 @@ func TestBadScriptJS(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := test.processor.Process(t.Context(), test.payload)
registration, ok := processor.ProcessorRegistry["script.js"]
if !ok {
t.Fatalf("script.js processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "script.js",
Params: test.params,
})
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("script.js expected to fail but succeeded, got: %v", got)

View File

@@ -2,7 +2,6 @@ package processor_test
import (
"testing"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
"github.com/jwetzell/showbridge-go/internal/processor"
@@ -53,37 +52,37 @@ func TestGoodStringCreate(t *testing.T) {
tests := []struct {
name string
template string
params map[string]any
payload any
expected string
}{
{
name: "string payload",
template: "{{.}}",
params: map[string]any{"template": "{{.}}"},
payload: "hello",
expected: "hello",
},
{
name: "number payload",
template: "{{.}}",
params: map[string]any{"template": "{{.}}"},
payload: 4,
expected: "4",
},
{
name: "boolean payload",
template: "{{.}}",
params: map[string]any{"template": "{{.}}"},
payload: true,
expected: "true",
},
{
name: "struct payload - field",
template: "{{.Data}}",
params: map[string]any{"template": "{{.Data}}"},
payload: TestStruct{Data: "test"},
expected: "test",
},
{
name: "struct payload - method",
template: "{{.GetData}}",
params: map[string]any{"template": "{{.GetData}}"},
payload: TestStruct{Data: "test"},
expected: "test",
},
@@ -91,14 +90,21 @@ func TestGoodStringCreate(t *testing.T) {
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
template, err := template.New("template").Parse(test.template)
if err != nil {
t.Fatalf("string.create template parsing failed: %s", err)
registration, ok := processor.ProcessorRegistry["string.create"]
if !ok {
t.Fatalf("string.create processor not registered")
}
processor := &processor.StringCreate{Template: template}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.create",
Params: test.params,
})
got, err := processor.Process(t.Context(), test.payload)
if err != nil {
t.Fatalf("string.create failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotStrings, ok := got.(string)
if !ok {

View File

@@ -118,8 +118,8 @@ func TestGoodStringFilter(t *testing.T) {
func TestBadStringFilter(t *testing.T) {
tests := []struct {
name string
payload any
params map[string]any
payload any
errorString string
}{
{

View File

@@ -49,22 +49,36 @@ func TestStringSplitFromRegistry(t *testing.T) {
func TestGoodStringSplit(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
expected []string
name string
params map[string]any
payload any
expected []string
}{
{
processor: &processor.StringSplit{Separator: ","},
name: "comma separated",
payload: "part1,part2,part3",
expected: []string{"part1", "part2", "part3"},
name: "comma separated",
params: map[string]any{"separator": ","},
payload: "part1,part2,part3",
expected: []string{"part1", "part2", "part3"},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := test.processor.Process(t.Context(), test.payload)
registration, ok := processor.ProcessorRegistry["string.split"]
if !ok {
t.Fatalf("string.split processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "string.split",
Params: test.params,
})
if err != nil {
t.Fatalf("string.split failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotStrings, ok := got.([]string)
if !ok {

View File

@@ -28,3 +28,36 @@ func TestTimeSleepFromRegistry(t *testing.T) {
t.Fatalf("time.sleep processor has wrong type: %s", processorInstance.Type())
}
}
func TestBadTimeSleep(t *testing.T) {
tests := []struct {
name string
params map[string]any
payload any
errorString string
}{}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
registration, ok := processor.ProcessorRegistry["time.sleep"]
if !ok {
t.Fatalf("time.sleep processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "time.sleep",
Params: test.params,
})
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("time.sleep expected to fail but succeeded, got: %v", got)
}
if err.Error() != test.errorString {
t.Fatalf("time.sleep got error '%s', expected '%s'", err.Error(), test.errorString)
}
})
}
}

View File

@@ -101,50 +101,54 @@ func TestUintParseGoodConfig(t *testing.T) {
func TestGoodUintParse(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
expected uint64
base int
bitSize int
name string
params map[string]any
payload any
expected uint64
}{
{
name: "positive number",
params: map[string]any{"base": 10.0, "bitSize": 64.0},
payload: "12345",
expected: 12345,
base: 10,
bitSize: 64,
},
{
name: "zero",
params: map[string]any{"base": 10.0, "bitSize": 64.0},
payload: "0",
expected: 0,
base: 10,
bitSize: 64,
},
{
name: "binary",
params: map[string]any{"base": 2.0, "bitSize": 64.0},
payload: "1010101",
expected: 85,
base: 2,
bitSize: 64,
},
{
name: "hex",
params: map[string]any{"base": 16.0, "bitSize": 64.0},
payload: "15F",
expected: 351,
base: 16,
bitSize: 64,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
uintParser := processor.UintParse{
Base: test.base,
BitSize: test.bitSize,
registration, ok := processor.ProcessorRegistry["uint.parse"]
if !ok {
t.Fatalf("uint.parse processor not registered")
}
got, err := uintParser.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "uint.parse",
Params: test.params,
})
if err != nil {
t.Fatalf("uint.parse failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotUint, ok := got.(uint64)
if !ok {
@@ -161,41 +165,45 @@ func TestGoodUintParse(t *testing.T) {
}
func TestBadUintParse(t *testing.T) {
uintParser := processor.UintParse{}
tests := []struct {
processor processor.Processor
name string
params map[string]any
payload any
base int
bitSize int
errorString string
}{
{
name: "non-string input",
params: map[string]any{"base": 10.0, "bitSize": 64.0},
payload: []byte{0x01},
base: 10,
bitSize: 64,
errorString: "uint.parse processor only accepts a string",
},
{
name: "not uint string",
params: map[string]any{"base": 10.0, "bitSize": 64.0},
payload: "-1234",
base: 10,
bitSize: 64,
errorString: "strconv.ParseUint: parsing \"-1234\": invalid syntax",
},
{
name: "bit overflow",
params: map[string]any{"base": 10.0, "bitSize": 32.0},
payload: "123456789012345678901234567",
base: 10,
bitSize: 32,
errorString: "strconv.ParseUint: parsing \"123456789012345678901234567\": value out of range",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := uintParser.Process(t.Context(), test.payload)
registration, ok := processor.ProcessorRegistry["uint.parse"]
if !ok {
t.Fatalf("uint.parse processor not registered")
}
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "uint.parse",
Params: test.params,
})
got, err := processorInstance.Process(t.Context(), test.payload)
if err == nil {
t.Fatalf("uint.parse expected to fail but succeeded, got: %v", got)

View File

@@ -68,27 +68,34 @@ func TestUintRandomGoodConfig(t *testing.T) {
func TestGoodUintRandom(t *testing.T) {
tests := []struct {
processor processor.Processor
name string
payload any
min uint
max uint
name string
params map[string]any
payload any
}{
{
name: "1-10",
params: map[string]any{"min": 1.0, "max": 10.0},
payload: "12345",
min: 1,
max: 10,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
uintRandom := processor.UintRandom{
Min: test.min,
Max: test.max,
registration, ok := processor.ProcessorRegistry["uint.random"]
if !ok {
t.Fatalf("uint.random processor not registered")
}
got, err := uintRandom.Process(t.Context(), test.payload)
processorInstance, err := registration.New(config.ProcessorConfig{
Type: "uint.random",
Params: test.params,
})
if err != nil {
t.Fatalf("uint.random failed to create processor: %s", err)
}
got, err := processorInstance.Process(t.Context(), test.payload)
gotUint, ok := got.(uint)
if !ok {
@@ -97,8 +104,16 @@ func TestGoodUintRandom(t *testing.T) {
if err != nil {
t.Fatalf("uint.random failed: %s", err)
}
if gotUint < test.min || gotUint > test.max {
t.Fatalf("uint.random got %d, expected between %d and %d", gotUint, test.min, test.max)
minNum, ok := test.params["min"].(float64)
if !ok {
t.Fatalf("uint.random test min param is not a number")
}
maxNum, ok := test.params["max"].(float64)
if !ok {
t.Fatalf("uint.random test max param is not a number")
}
if gotUint < uint(minNum) || gotUint > uint(maxNum) {
t.Fatalf("uint.random got %d, expected between %d and %d", gotUint, uint(minNum), uint(maxNum))
}
})
}