github.com/Jeffail/benthos/v3@v3.65.0/lib/processor/number_test.go (about)

     1  package processor
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/Jeffail/benthos/v3/lib/log"
     9  	"github.com/Jeffail/benthos/v3/lib/message"
    10  	"github.com/Jeffail/benthos/v3/lib/metrics"
    11  	"github.com/Jeffail/benthos/v3/lib/types"
    12  )
    13  
    14  func TestNumberBasic(t *testing.T) {
    15  	type testCase struct {
    16  		name     string
    17  		operator string
    18  		value    interface{}
    19  		input    []string
    20  		output   []string
    21  	}
    22  
    23  	tests := []testCase{
    24  		{
    25  			name:     "add float64 1",
    26  			operator: "add",
    27  			value:    5.0,
    28  			input: []string{
    29  				"6", "10.1",
    30  			},
    31  			output: []string{
    32  				"11", "15.1",
    33  			},
    34  		},
    35  		{
    36  			name:     "add int 1",
    37  			operator: "add",
    38  			value:    5,
    39  			input: []string{
    40  				"6", "10.1",
    41  			},
    42  			output: []string{
    43  				"11", "15.1",
    44  			},
    45  		},
    46  		{
    47  			name:     "add json.Number 1",
    48  			operator: "add",
    49  			value:    json.Number("5"),
    50  			input: []string{
    51  				"6", "10.1",
    52  			},
    53  			output: []string{
    54  				"11", "15.1",
    55  			},
    56  		},
    57  		{
    58  			name:     "add string 1",
    59  			operator: "add",
    60  			value:    "5",
    61  			input: []string{
    62  				"6", "10.1",
    63  			},
    64  			output: []string{
    65  				"11", "15.1",
    66  			},
    67  		},
    68  		{
    69  			name:     "add interpolated string 1",
    70  			operator: "add",
    71  			value:    "${!batch_size()}",
    72  			input: []string{
    73  				"6", "10.1",
    74  			},
    75  			output: []string{
    76  				"8", "12.1",
    77  			},
    78  		},
    79  		{
    80  			name:     "subtract float64 1",
    81  			operator: "subtract",
    82  			value:    5.0,
    83  			input: []string{
    84  				"6", "10.1",
    85  			},
    86  			output: []string{
    87  				"1", "5.1",
    88  			},
    89  		},
    90  		{
    91  			name:     "subtract int 1",
    92  			operator: "subtract",
    93  			value:    5,
    94  			input: []string{
    95  				"6", "10.1",
    96  			},
    97  			output: []string{
    98  				"1", "5.1",
    99  			},
   100  		},
   101  		{
   102  			name:     "subtract json.Number 1",
   103  			operator: "subtract",
   104  			value:    json.Number("5"),
   105  			input: []string{
   106  				"6", "10.1",
   107  			},
   108  			output: []string{
   109  				"1", "5.1",
   110  			},
   111  		},
   112  		{
   113  			name:     "subtract string 1",
   114  			operator: "subtract",
   115  			value:    "5",
   116  			input: []string{
   117  				"6", "10.1",
   118  			},
   119  			output: []string{
   120  				"1", "5.1",
   121  			},
   122  		},
   123  		{
   124  			name:     "subtract interpolated string 1",
   125  			operator: "subtract",
   126  			value:    "${!batch_size()}",
   127  			input: []string{
   128  				"6", "10.1",
   129  			},
   130  			output: []string{
   131  				"4", "8.1",
   132  			},
   133  		},
   134  	}
   135  
   136  	for _, test := range tests {
   137  		t.Run(test.name, func(tt *testing.T) {
   138  			conf := NewConfig()
   139  			conf.Type = TypeNumber
   140  			conf.Number.Value = test.value
   141  			conf.Number.Operator = test.operator
   142  
   143  			proc, err := New(conf, nil, log.Noop(), metrics.Noop())
   144  			if err != nil {
   145  				tt.Fatal(err)
   146  			}
   147  
   148  			input := message.New(nil)
   149  			for _, p := range test.input {
   150  				input.Append(message.NewPart([]byte(p)))
   151  			}
   152  
   153  			exp := make([][]byte, len(test.output))
   154  			for i, p := range test.output {
   155  				exp[i] = []byte(p)
   156  			}
   157  
   158  			msgs, res := proc.ProcessMessage(input)
   159  			if res != nil {
   160  				tt.Fatal(res.Error())
   161  			}
   162  
   163  			if len(msgs) != 1 {
   164  				tt.Fatalf("Expected one message, received: %v", len(msgs))
   165  			}
   166  			if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(act, exp) {
   167  				tt.Errorf("Unexpected output: %s != %s", exp, act)
   168  			}
   169  		})
   170  	}
   171  }
   172  
   173  func TestNumberBadContent(t *testing.T) {
   174  	conf := NewConfig()
   175  	conf.Type = TypeNumber
   176  	conf.Number.Value = "5"
   177  	conf.Number.Operator = "add"
   178  
   179  	proc, err := New(conf, nil, log.Noop(), metrics.Noop())
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  
   184  	input := message.New([][]byte{
   185  		[]byte("nope"),
   186  		[]byte("7"),
   187  	})
   188  
   189  	exp := [][]byte{
   190  		[]byte("nope"),
   191  		[]byte("12"),
   192  	}
   193  
   194  	msgs, res := proc.ProcessMessage(input)
   195  	if res != nil {
   196  		t.Fatal(res.Error())
   197  	}
   198  
   199  	if len(msgs) != 1 {
   200  		t.Fatalf("Expected one message, received: %v", len(msgs))
   201  	}
   202  	if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(act, exp) {
   203  		t.Errorf("Unexpected output: %s != %s", exp, act)
   204  	}
   205  
   206  	msgs[0].Iter(func(i int, p types.Part) error {
   207  		if i == 0 {
   208  			if !HasFailed(p) {
   209  				t.Error("Expected fail flag")
   210  			}
   211  		} else if HasFailed(p) {
   212  			t.Error("Expected fail flag")
   213  		}
   214  		return nil
   215  	})
   216  }
   217  
   218  func TestNumberBadInterpolatedValue(t *testing.T) {
   219  	conf := NewConfig()
   220  	conf.Type = TypeNumber
   221  	conf.Number.Value = "${!batch_size()} but this is never a number"
   222  	conf.Number.Operator = "add"
   223  
   224  	proc, err := New(conf, nil, log.Noop(), metrics.Noop())
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  
   229  	input := message.New([][]byte{
   230  		[]byte("11"),
   231  		[]byte("7"),
   232  	})
   233  
   234  	exp := [][]byte{
   235  		[]byte("11"),
   236  		[]byte("7"),
   237  	}
   238  
   239  	msgs, res := proc.ProcessMessage(input)
   240  	if res != nil {
   241  		t.Fatal(res.Error())
   242  	}
   243  
   244  	if len(msgs) != 1 {
   245  		t.Fatalf("Expected one message, received: %v", len(msgs))
   246  	}
   247  	if act := message.GetAllBytes(msgs[0]); !reflect.DeepEqual(act, exp) {
   248  		t.Errorf("Unexpected output: %s != %s", exp, act)
   249  	}
   250  	msgs[0].Iter(func(i int, p types.Part) error {
   251  		if !HasFailed(p) {
   252  			t.Error("Expected fail flag")
   253  		}
   254  		return nil
   255  	})
   256  }