// ObjectGoPrintDiff is like ObjectDiff, but uses go-spew to print the objects, // which shows absolutely everything by recursing into every single pointer // (go's %#v formatters OTOH stop at a certain point). This is needed when you // can't figure out why reflect.DeepEqual is returning false and nothing is // showing you differences. This will. func ObjectGoPrintDiff(a, b interface{}) string { s := spew.ConfigState{DisableMethods: true} return StringDiff( s.Sprintf("%#v", a), s.Sprintf("%#v", b), ) }
func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { printer := spew.ConfigState{DisableMethods: true} gvk, err := api.Scheme.ObjectKind(item) t.Logf("fully qualified kind for %v is %v with codec %v", reflect.TypeOf(item), gvk, codec) name := reflect.TypeOf(item).Elem().Name() data, err := codec.Encode(item) if err != nil { t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item)) return } obj2, err := codec.Decode(data) if err != nil { t.Errorf("0: %v: %v\nCodec: %v\nData: %s\nSource: %#v", name, err, codec, string(data), printer.Sprintf("%#v", item)) return } if !api.Semantic.DeepEqual(item, obj2) { t.Errorf("\n1: %v: diff: %v\nCodec: %v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, util.ObjectGoPrintDiff(item, obj2), codec, printer.Sprintf("%#v", item), string(data), printer.Sprintf("%#v", obj2)) return } obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) err = codec.DecodeInto(data, obj3) if err != nil { t.Errorf("2: %v: %v", name, err) return } if !api.Semantic.DeepEqual(item, obj3) { t.Errorf("3: %v: diff: %v\nCodec: %v", name, util.ObjectDiff(item, obj3), codec) return } }
func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { //t.Logf("codec: %#v", codec) printer := spew.ConfigState{DisableMethods: true} name := reflect.TypeOf(item).Elem().Name() data, err := runtime.Encode(codec, item) if err != nil { t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item)) return } obj2, err := runtime.Decode(codec, data) if err != nil { t.Errorf("0: %v: %v\nCodec: %v\nData: %s\nSource: %#v", name, err, codec, string(data), printer.Sprintf("%#v", item)) return } if !api.Semantic.DeepEqual(item, obj2) { t.Errorf("\n1: %v: diff: %v\nCodec: %v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectGoPrintDiff(item, obj2), codec, printer.Sprintf("%#v", item), string(data), printer.Sprintf("%#v", obj2)) return } obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Errorf("2: %v: %v", name, err) return } if !api.Semantic.DeepEqual(item, obj3) { t.Errorf("3: %v: diff: %v\nCodec: %v", name, diff.ObjectDiff(item, obj3), codec) return } }
// roundTrip applies a single round-trip test to the given runtime object // using the given codec. The round-trip test ensures that an object can be // deep-copied and converted from internal -> versioned -> internal without // loss of data. func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { printer := spew.ConfigState{DisableMethods: true} original := item // deep copy the original object copied, err := api.Scheme.DeepCopy(item) if err != nil { panic(fmt.Sprintf("unable to copy: %v", err)) } item = copied.(runtime.Object) name := reflect.TypeOf(item).Elem().Name() // encode (serialize) the deep copy using the provided codec data, err := runtime.Encode(codec, item) if err != nil { if runtime.IsNotRegisteredError(err) { t.Logf("%v: not registered: %v (%s)", name, err, printer.Sprintf("%#v", item)) } else { t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item)) } return } // ensure that the deep copy is equal to the original; neither the deep // copy or conversion should alter the object if !api.Semantic.DeepEqual(original, item) { t.Errorf("0: %v: encode altered the object, diff: %v", name, diff.ObjectReflectDiff(original, item)) return } // decode (deserialize) the encoded data back into an object obj2, err := runtime.Decode(codec, data) if err != nil { t.Errorf("0: %v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), printer.Sprintf("%#v", item)) panic("failed") } // ensure that the object produced from decoding the encoded data is equal // to the original object if !api.Semantic.DeepEqual(original, obj2) { t.Errorf("\n1: %v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(item, obj2), codec, printer.Sprintf("%#v", item), dataAsString(data), printer.Sprintf("%#v", obj2)) return } // decode the encoded data into a new object (instead of letting the codec // create a new object) obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Errorf("2: %v: %v", name, err) return } // ensure that the new runtime object is equal to the original after being // decoded into if !api.Semantic.DeepEqual(item, obj3) { t.Errorf("3: %v: diff: %v\nCodec: %#v", name, diff.ObjectReflectDiff(item, obj3), codec) return } }
func roundTrip(t *testing.T, codec runtime.Codec, item runtime.Object) { printer := spew.ConfigState{DisableMethods: true} original := item copied, err := api.Scheme.DeepCopy(item) if err != nil { panic(fmt.Sprintf("unable to copy: %v", err)) } item = copied.(runtime.Object) name := reflect.TypeOf(item).Elem().Name() data, err := runtime.Encode(codec, item) if err != nil { if runtime.IsNotRegisteredError(err) { t.Logf("%v: not registered: %v (%s)", name, err, printer.Sprintf("%#v", item)) } else { t.Errorf("%v: %v (%s)", name, err, printer.Sprintf("%#v", item)) } return } if !api.Semantic.DeepEqual(original, item) { t.Errorf("0: %v: encode altered the object, diff: %v", name, diff.ObjectReflectDiff(original, item)) return } obj2, err := runtime.Decode(codec, data) if err != nil { t.Errorf("0: %v: %v\nCodec: %#v\nData: %s\nSource: %#v", name, err, codec, dataAsString(data), printer.Sprintf("%#v", item)) panic("failed") } if !api.Semantic.DeepEqual(original, obj2) { t.Errorf("\n1: %v: diff: %v\nCodec: %#v\nSource:\n\n%#v\n\nEncoded:\n\n%s\n\nFinal:\n\n%#v", name, diff.ObjectReflectDiff(item, obj2), codec, printer.Sprintf("%#v", item), dataAsString(data), printer.Sprintf("%#v", obj2)) return } obj3 := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) if err := runtime.DecodeInto(codec, data, obj3); err != nil { t.Errorf("2: %v: %v", name, err) return } if !api.Semantic.DeepEqual(item, obj3) { t.Errorf("3: %v: diff: %v\nCodec: %#v", name, diff.ObjectReflectDiff(item, obj3), codec) return } }
// DeepHashObject writes specified object to hash using the spew library // which follows pointers and prints actual values of the nested objects // ensuring the hash does not change when a pointer changes. func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { hasher.Reset() printer := spew.ConfigState{ Indent: " ", SortKeys: true, DisableMethods: true, SpewKeys: true, } printer.Fprintf(hasher, "%#v", objectToWrite) }
func TestDumpSortedKeys(t *testing.T) { cfg := spew.ConfigState{SortKeys: true} s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"}) expected := `(map[int]string) (len=3) { (int) 1: (string) (len=1) "1", (int) 2: (string) (len=1) "2", (int) 3: (string) (len=1) "3" } ` if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } }
func (flag *OutputFlag) WriteResult(result OutputWriter) error { var err error if flag.JSON { err = json.NewEncoder(flag.Out).Encode(result) } else if flag.Dump { scs := spew.ConfigState{Indent: " "} scs.Fdump(flag.Out, result) } else { err = result.Write(flag.Out) } return err }
// This example demonstrates how to use a ConfigState. func ExampleConfigState() { // Modify the indent level of the ConfigState only. The global // configuration is not modified. scs := spew.ConfigState{Indent: "\t"} // Output using the ConfigState instance. v := map[string]int{"one": 1} scs.Printf("v: %v\n", v) scs.Dump(v) // Output: // v: map[one:1] // (map[string]int) (len=1) { // (string) (len=3) "one": (int) 1 // } }
func TestDumpSortedKeys(t *testing.T) { cfg := spew.ConfigState{SortKeys: true} s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"}) expected := "(map[int]string) (len=3) {\n(int) 1: (string) (len=1) " + "\"1\",\n(int) 2: (string) (len=1) \"2\",\n(int) 3: (string) " + "(len=1) \"3\"\n" + "}\n" if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2}) expected = "(map[spew_test.stringer]int) (len=3) {\n" + "(spew_test.stringer) (len=1) stringer 1: (int) 1,\n" + "(spew_test.stringer) (len=1) stringer 2: (int) 2,\n" + "(spew_test.stringer) (len=1) stringer 3: (int) 3\n" + "}\n" if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2}) expected = "(map[spew_test.pstringer]int) (len=3) {\n" + "(spew_test.pstringer) (len=1) stringer 1: (int) 1,\n" + "(spew_test.pstringer) (len=1) stringer 2: (int) 2,\n" + "(spew_test.pstringer) (len=1) stringer 3: (int) 3\n" + "}\n" if spew.UnsafeDisabled { expected = "(map[spew_test.pstringer]int) (len=3) {\n" + "(spew_test.pstringer) (len=1) \"1\": (int) 1,\n" + "(spew_test.pstringer) (len=1) \"2\": (int) 2,\n" + "(spew_test.pstringer) (len=1) \"3\": (int) 3\n" + "}\n" } if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2}) expected = "(map[spew_test.customError]int) (len=3) {\n" + "(spew_test.customError) error: 1: (int) 1,\n" + "(spew_test.customError) error: 2: (int) 2,\n" + "(spew_test.customError) error: 3: (int) 3\n" + "}\n" if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } }
// ObjectGoPrintSideBySide prints a and b as textual dumps side by side, // enabling easy visual scanning for mismatches. func ObjectGoPrintSideBySide(a, b interface{}) string { s := spew.ConfigState{ Indent: " ", // Extra deep spew. DisableMethods: true, } sA := s.Sdump(a) sB := s.Sdump(b) linesA := strings.Split(sA, "\n") linesB := strings.Split(sB, "\n") width := 0 for _, s := range linesA { l := len(s) if l > width { width = l } } for _, s := range linesB { l := len(s) if l > width { width = l } } buf := &bytes.Buffer{} w := tabwriter.NewWriter(buf, width, 0, 1, ' ', 0) max := len(linesA) if len(linesB) > max { max = len(linesB) } for i := 0; i < max; i++ { var a, b string if i < len(linesA) { a = linesA[i] } if i < len(linesB) { b = linesB[i] } fmt.Fprintf(w, "%s\t%s\n", a, b) } w.Flush() return buf.String() }
func TestDumpSortedKeys(t *testing.T) { cfg := spew.ConfigState{SortKeys: true} s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"}) expected := `(map[int]string) (len=3) { (int) 1: (string) (len=1) "1", (int) 2: (string) (len=1) "2", (int) 3: (string) (len=1) "3" } ` if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2}) expected = `(map[spew_test.stringer]int) (len=3) { (spew_test.stringer) (len=1) stringer 1: (int) 1, (spew_test.stringer) (len=1) stringer 2: (int) 2, (spew_test.stringer) (len=1) stringer 3: (int) 3 } ` if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2}) expected = `(map[spew_test.pstringer]int) (len=3) { (spew_test.pstringer) (len=1) stringer 1: (int) 1, (spew_test.pstringer) (len=1) stringer 2: (int) 2, (spew_test.pstringer) (len=1) stringer 3: (int) 3 } ` if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2}) expected = `(map[spew_test.customError]int) (len=3) { (spew_test.customError) error: 1: (int) 1, (spew_test.customError) error: 2: (int) 2, (spew_test.customError) error: 3: (int) 3 } ` if s != expected { t.Errorf("Sorted keys mismatch:\n %v %v", s, expected) } }
func TestImportImageQuayIO(t *testing.T) { rt, _ := kclient.TransportFor(&kclient.Config{}) importCtx := importer.NewContext(rt).WithCredentials(importer.NoCredentials) imports := &api.ImageStreamImport{ Spec: api.ImageStreamImportSpec{ Images: []api.ImageImportSpec{ {From: kapi.ObjectReference{Kind: "DockerImage", Name: "quay.io/coreos/etcd"}}, }, }, } i := importer.NewImageStreamImporter(importCtx, 3, nil) if err := i.Import(gocontext.Background(), imports); err != nil { t.Fatal(err) } if imports.Status.Repository != nil { t.Errorf("unexpected repository: %#v", imports.Status.Repository) } if len(imports.Status.Images) != 1 { t.Fatalf("unexpected response: %#v", imports.Status.Images) } d := imports.Status.Images[0] if d.Status.Status != unversioned.StatusSuccess { if d.Status.Reason == "NotV2Registry" { t.Skipf("the server did not report as a v2 registry: %#v", d.Status) } t.Fatalf("unexpected error: %#v", d.Status) } if d.Image == nil || len(d.Image.DockerImageManifest) == 0 || !strings.HasPrefix(d.Image.DockerImageReference, "quay.io/coreos/etcd@") || len(d.Image.DockerImageMetadata.ID) == 0 || len(d.Image.DockerImageLayers) == 0 { t.Errorf("unexpected object: %#v", d.Image) s := spew.ConfigState{ Indent: " ", // Extra deep spew. DisableMethods: true, } t.Logf("import: %s", s.Sdump(d)) } }
func TestDecode(t *testing.T) { scs := spew.ConfigState{Indent: "\t", ContinueOnMethod: true} for i, tt := range decodeTests { if tt.ptr == nil { continue } // v = new(right-type) v := reflect.New(reflect.TypeOf(tt.ptr).Elem()) if err := Decode(v.Interface(), tt.in); !reflect.DeepEqual(err, tt.err) { t.Errorf("#%d: got error %v want %v", i, err, tt.err) continue } if !reflect.DeepEqual(v.Elem().Interface(), tt.out) { scs.Dump(v.Elem().Interface(), tt.out) t.Errorf("#%d: mismatch\nhave: %+v\nwant: %+v", i, v.Elem().Interface(), tt.out) continue } // Check round trip. if tt.err == nil { enc, err := Encode(v.Interface()) if err != nil { t.Errorf("#%d: error re-marshaling: %v", i, err) continue } vv := reflect.New(reflect.TypeOf(tt.ptr).Elem()) if err := Decode(vv.Interface(), enc); err != nil { t.Errorf("#%d: error re-decodeing: %v", i, err) continue } if !reflect.DeepEqual(v.Elem().Interface(), vv.Elem().Interface()) { t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface()) continue } } } }
// This example demonstrates how to use ConfigState.Dump to dump variables to // stdout func ExampleConfigState_Dump() { // See the top-level Dump example for details on the types used in this // example. // Create two ConfigState instances with different indentation. scs := spew.ConfigState{Indent: "\t"} scs2 := spew.ConfigState{Indent: " "} // Setup some sample data structures for the example. bar := Bar{uintptr(0)} s1 := Foo{bar, map[interface{}]interface{}{"one": true}} // Dump using the ConfigState instances. scs.Dump(s1) scs2.Dump(s1) // Output: // (spew_test.Foo) { // unexportedField: (spew_test.Bar) { // data: (uintptr) <nil> // }, // ExportedField: (map[interface {}]interface {}) (len=1) { // (string) (len=3) "one": (bool) true // } // } // (spew_test.Foo) { // unexportedField: (spew_test.Bar) { // data: (uintptr) <nil> // }, // ExportedField: (map[interface {}]interface {}) (len=1) { // (string) (len=3) "one": (bool) true // } // } // }
func Test_quick(t *testing.T) { LogOn() unit := 32 plot := Plot{ File{"out.pdf"}, PageConfig{ Width: unit * 4, Height: unit * 3, NSubpageX: 1, NSubpageY: 2, }, LineWidth{0.2}, Subpage{ //Viewport{XMin: 0, XMax: 0.5, YMin: 0, YMax: 1}, Block{ PolyLine{[]float64{0, 3}, []float64{0, 3}}, }, Axis{Position: TOP | RIGHT | LEFT | BOTTOM}, Legend{ Option: LEGEND_BACKGROUND | LEGEND_BOUNDING_BOX, Position: TOP | RIGHT | INSIDE | VIEWPORT, Offset: LegendOffset{0.02, 0.02}, PlotWidth: 0.05, BackColor: 0, Box: BoundingBox{1, 1}, OptionArray: []LegendType{LEGEND_LINE, LEGEND_LINE, LEGEND_LINE, LEGEND_LINE}, Text: TextLegend{Offset: 0.5, Scale: 0.8, Spacing: 1.5, Justification: 1.0, Colors: []int{1, 1, 1, 1}, Texts: []string{"k=1", "k=2", "k=3", "k=4"}}, Line: LineLegend{Colors: []int{3, 5, 8, 11}, Styles: []int{1, 1, 1, 1}, Widths: []float64{0.2, 0.2, 0.2, 0.2}}, }, }, Subpage{}, } pp := spew.ConfigState{Indent: " "} prepared := plot.Prepare() pp.Dump(prepared) prepared.Do() }
// DeepHashObject writes specified object to hash using the spew library // which follows pointers and prints actual values of the nested objects // ensuring the hash does not change when a pointer changes. func DeepHashObject(hasher hash.Hash, objectToWrite interface{}) { printer := spew.ConfigState{Indent: " ", SortKeys: true} printer.Fprintf(hasher, "%#v", objectToWrite) }