github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/eval/vals/concat_test.go (about) 1 package vals 2 3 import ( 4 "errors" 5 "math/big" 6 "testing" 7 8 . "github.com/markusbkk/elvish/pkg/tt" 9 ) 10 11 // An implementation for Concatter that accepts strings, returns a special 12 // error when rhs is a float64, and returns ErrConcatNotImplemented when rhs is 13 // of other types. 14 type concatter struct{} 15 16 var errBadFloat64 = errors.New("float64 is bad") 17 18 func (concatter) Concat(rhs interface{}) (interface{}, error) { 19 switch rhs := rhs.(type) { 20 case string: 21 return "concatter " + rhs, nil 22 case float64: 23 return nil, errBadFloat64 24 default: 25 return nil, ErrConcatNotImplemented 26 } 27 } 28 29 // An implementation of RConcatter that accepts all types. 30 type rconcatter struct{} 31 32 func (rconcatter) RConcat(lhs interface{}) (interface{}, error) { 33 return "rconcatter", nil 34 } 35 36 func TestConcat(t *testing.T) { 37 Test(t, Fn("Concat", Concat), Table{ 38 Args("foo", "bar").Rets("foobar", nil), 39 // string+number 40 Args("foo", 2).Rets("foo2", nil), 41 Args("foo", bigInt(z)).Rets("foo"+z, nil), 42 Args("foo", big.NewRat(1, 2)).Rets("foo1/2", nil), 43 Args("foo", 2.0).Rets("foo2.0", nil), 44 // number+string 45 Args(2, "foo").Rets("2foo", nil), 46 Args(bigInt(z), "foo").Rets(z+"foo", nil), 47 Args(big.NewRat(1, 2), "foo").Rets("1/2foo", nil), 48 Args(2.0, "foo").Rets("2.0foo", nil), 49 50 // LHS implements Concatter and succeeds 51 Args(concatter{}, "bar").Rets("concatter bar", nil), 52 // LHS implements Concatter but returns ErrConcatNotImplemented; RHS 53 // does not implement RConcatter 54 Args(concatter{}, 12).Rets(nil, cannotConcat{"!!vals.concatter", "number"}), 55 // LHS implements Concatter but returns another error 56 Args(concatter{}, 12.0).Rets(nil, errBadFloat64), 57 58 // LHS does not implement Concatter but RHS implements RConcatter 59 Args(12, rconcatter{}).Rets("rconcatter", nil), 60 }) 61 }