diff --git a/internal/processor/test/artnet-packet-filter_test.go b/internal/processor/test/artnet-packet-filter_test.go index a7ddbd5..8c17af9 100644 --- a/internal/processor/test/artnet-packet-filter_test.go +++ b/internal/processor/test/artnet-packet-filter_test.go @@ -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 }{ { diff --git a/internal/processor/test/float-parse_test.go b/internal/processor/test/float-parse_test.go index 0002a04..8db9e1a 100644 --- a/internal/processor/test/float-parse_test.go +++ b/internal/processor/test/float-parse_test.go @@ -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) diff --git a/internal/processor/test/int-parse_test.go b/internal/processor/test/int-parse_test.go index 54fd192..0e3abcb 100644 --- a/internal/processor/test/int-parse_test.go +++ b/internal/processor/test/int-parse_test.go @@ -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) diff --git a/internal/processor/test/int-random_test.go b/internal/processor/test/int-random_test.go index 521abd0..1d89fee 100644 --- a/internal/processor/test/int-random_test.go +++ b/internal/processor/test/int-random_test.go @@ -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)) } }) } diff --git a/internal/processor/test/midi-message-encode_test.go b/internal/processor/test/midi-message-encode_test.go index 441b405..d742e90 100644 --- a/internal/processor/test/midi-message-encode_test.go +++ b/internal/processor/test/midi-message-encode_test.go @@ -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) + } + }) + } +} diff --git a/internal/processor/test/midi-message-filter_test.go b/internal/processor/test/midi-message-filter_test.go index e98aaab..bf92cca 100644 --- a/internal/processor/test/midi-message-filter_test.go +++ b/internal/processor/test/midi-message-filter_test.go @@ -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) + } + }) + } +} diff --git a/internal/processor/test/script-expr_test.go b/internal/processor/test/script-expr_test.go index 8c9d482..a85ad93 100644 --- a/internal/processor/test/script-expr_test.go +++ b/internal/processor/test/script-expr_test.go @@ -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) diff --git a/internal/processor/test/script-js_test.go b/internal/processor/test/script-js_test.go index 42b5d18..05ef793 100644 --- a/internal/processor/test/script-js_test.go +++ b/internal/processor/test/script-js_test.go @@ -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) diff --git a/internal/processor/test/string-create_test.go b/internal/processor/test/string-create_test.go index 764cecd..375780e 100644 --- a/internal/processor/test/string-create_test.go +++ b/internal/processor/test/string-create_test.go @@ -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 { diff --git a/internal/processor/test/string-filter_test.go b/internal/processor/test/string-filter_test.go index 1de2e99..df823d0 100644 --- a/internal/processor/test/string-filter_test.go +++ b/internal/processor/test/string-filter_test.go @@ -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 }{ { diff --git a/internal/processor/test/string-split_test.go b/internal/processor/test/string-split_test.go index f76a9a8..6c2b665 100644 --- a/internal/processor/test/string-split_test.go +++ b/internal/processor/test/string-split_test.go @@ -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 { diff --git a/internal/processor/test/time-sleep_test.go b/internal/processor/test/time-sleep_test.go index 3a0b41c..19c4345 100644 --- a/internal/processor/test/time-sleep_test.go +++ b/internal/processor/test/time-sleep_test.go @@ -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) + } + }) + } +} diff --git a/internal/processor/test/uint-parse_test.go b/internal/processor/test/uint-parse_test.go index 8e60df3..80415a4 100644 --- a/internal/processor/test/uint-parse_test.go +++ b/internal/processor/test/uint-parse_test.go @@ -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) diff --git a/internal/processor/test/uint-random_test.go b/internal/processor/test/uint-random_test.go index 9270de8..e80b910 100644 --- a/internal/processor/test/uint-random_test.go +++ b/internal/processor/test/uint-random_test.go @@ -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)) } }) }