...

Source file src/edge-infra.dev/pkg/lib/cli/clog/clog_test.go

Documentation: edge-infra.dev/pkg/lib/cli/clog

     1  package clog
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  )
     7  
     8  // Logging this should result in the MarshalLog() value.
     9  type Tmarshaler struct{ val string }
    10  
    11  func (t Tmarshaler) MarshalLog() any {
    12  	return struct{ Inner string }{"I am a logr.Marshaler"}
    13  }
    14  
    15  func (t Tmarshaler) String() string {
    16  	return "String(): you should not see this"
    17  }
    18  
    19  func (t Tmarshaler) Error() string {
    20  	return "Error(): you should not see this"
    21  }
    22  
    23  // Logging this should result in a panic.
    24  type Tmarshalerpanic struct{ val string }
    25  
    26  func (t Tmarshalerpanic) MarshalLog() any {
    27  	panic("Tmarshalerpanic")
    28  }
    29  
    30  // Logging this should result in the String() value.
    31  type Tstringer struct{ val string }
    32  
    33  func (t Tstringer) String() string {
    34  	return "I am a fmt.Stringer"
    35  }
    36  
    37  func (t Tstringer) Error() string {
    38  	return "Error(): you should not see this"
    39  }
    40  
    41  // Logging this should result in a panic.
    42  type Tstringerpanic struct{ val string }
    43  
    44  func (t Tstringerpanic) String() string {
    45  	panic("Tstringerpanic")
    46  }
    47  
    48  // Logging this should result in the Error() value.
    49  type Terror struct{ val string }
    50  
    51  func (t Terror) Error() string {
    52  	return "I am an error"
    53  }
    54  
    55  // Logging this should result in a panic.
    56  type Terrorpanic struct{ val string }
    57  
    58  func (t Terrorpanic) Error() string {
    59  	panic("Terrorpanic")
    60  }
    61  
    62  func TestPretty(t *testing.T) {
    63  	cases := []struct {
    64  		val any
    65  		exp string // used in cases where JSON can't handle it
    66  	}{
    67  		{
    68  			val: "strval",
    69  			exp: "strval",
    70  		}, {
    71  			val: "strval\nwith\t\"escapes\"",
    72  		}, {
    73  			val: true,
    74  		}, {
    75  			val: false,
    76  		}, {
    77  			val: int(93),
    78  		}, {
    79  			val: int8(93),
    80  		}, {
    81  			val: int16(93),
    82  		}, {
    83  			val: int32(93),
    84  		}, {
    85  			val: int64(93),
    86  		}, {
    87  			val: int(-93),
    88  		}, {
    89  			val: int8(-93),
    90  		}, {
    91  			val: int16(-93),
    92  		}, {
    93  			val: int32(-93),
    94  		}, {
    95  			val: int64(-93),
    96  		}, {
    97  			val: uint(93),
    98  		}, {
    99  			val: uint8(93),
   100  		}, {
   101  			val: uint16(93),
   102  		}, {
   103  			val: uint32(93),
   104  		}, {
   105  			val: uint64(93),
   106  		}, {
   107  			val: uintptr(93),
   108  		}, {
   109  			val: float32(93.76),
   110  		}, {
   111  			val: float64(93.76),
   112  		}, {
   113  			val: complex64(93i),
   114  			exp: `"(0+93i)"`,
   115  		}, {
   116  			val: complex128(93i),
   117  			exp: `"(0+93i)"`,
   118  		}, {
   119  			val: Tmarshaler{"foobar"},
   120  			exp: "{Inner:I am a logr.Marshaler}",
   121  		}, {
   122  			val: &Tmarshaler{"foobar"},
   123  			exp: "{Inner:I am a logr.Marshaler}",
   124  		}, {
   125  			val: (*Tmarshaler)(nil),
   126  			exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Tmarshaler.MarshalLog called using nil *Tmarshaler pointer>",
   127  		}, {
   128  			val: Tmarshalerpanic{"foobar"},
   129  			exp: "<panic: Tmarshalerpanic>",
   130  		}, {
   131  			val: Tstringer{"foobar"},
   132  			exp: "I am a fmt.Stringer",
   133  		}, {
   134  			val: &Tstringer{"foobar"},
   135  			exp: "I am a fmt.Stringer",
   136  		}, {
   137  			val: (*Tstringer)(nil),
   138  			exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Tstringer.String called using nil *Tstringer pointer>",
   139  		}, {
   140  			val: Tstringerpanic{"foobar"},
   141  			exp: "<panic: Tstringerpanic>",
   142  		}, {
   143  			val: Terror{"foobar"},
   144  			exp: "I am an error",
   145  		}, {
   146  			val: &Terror{"foobar"},
   147  			exp: "I am an error",
   148  		}, {
   149  			val: (*Terror)(nil),
   150  			exp: "<panic: value method edge-infra.dev/pkg/lib/cli/clog.Terror.Error called using nil *Terror pointer>",
   151  		}, {
   152  			val: Terrorpanic{"foobar"},
   153  			exp: "<panic: Terrorpanic>",
   154  		}, {
   155  			val: []string{"foo", "bar"},
   156  			exp: "\n    foo\n    bar",
   157  		}, {
   158  			val: map[string]string{
   159  				"foo": "bar",
   160  				"yes": "no",
   161  			},
   162  			exp: "\n    foo  bar\n    yes  no",
   163  		}, {
   164  			val: map[string]string{
   165  				"yes": "",
   166  				"foo": "bar",
   167  			},
   168  			exp: "\n    foo  bar",
   169  		}, {
   170  			val: map[string]string{
   171  				"foo": "bar",
   172  				"yes": "",
   173  			},
   174  			exp: "\n    foo  bar",
   175  		}, {
   176  			val: map[string]string{
   177  				"no":  "",
   178  				"foo": "bar",
   179  				"yes": "",
   180  				"op":  "delete",
   181  			},
   182  			exp: "\n    foo  bar\n    op   delete",
   183  		},
   184  		// TODO: non-string slices, non-string values in map (TextMarshaler & !TextMarshaler), slice in map, etc
   185  	}
   186  
   187  	for i, tc := range cases {
   188  		l := &clog{tabWidth: 2}
   189  		ours := l.pretty(tc.val)
   190  		want := ""
   191  		if tc.exp != "" {
   192  			want = tc.exp
   193  		} else {
   194  			jb, err := json.Marshal(tc.val)
   195  			if err != nil {
   196  				t.Fatalf("[%d]: unexpected error: %v\ngot: %q", i, err, ours)
   197  			}
   198  			want = string(jb)
   199  		}
   200  		if ours != want {
   201  			t.Errorf("[%d]:\n\texpected %q\n\tgot      %q", i, want, ours)
   202  		}
   203  	}
   204  }
   205  

View as plain text