github.com/ndau/noms@v1.0.5/go/types/encode_human_readable_test.go (about)

     1  // Copyright 2016 Attic Labs, Inc. All rights reserved.
     2  // Licensed under the Apache License, version 2.0:
     3  // http://www.apache.org/licenses/LICENSE-2.0
     4  
     5  package types
     6  
     7  import (
     8  	"bytes"
     9  	"errors"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/ndau/noms/go/util/test"
    14  	"github.com/stretchr/testify/assert"
    15  )
    16  
    17  func assertWriteHRSEqual(t *testing.T, expected string, v Value) {
    18  	assert := assert.New(t)
    19  	var buf bytes.Buffer
    20  	w := &hrsWriter{w: &buf, floatFormat: 'g'}
    21  	w.Write(v)
    22  	assert.Equal(test.RemoveHashes(expected), test.RemoveHashes(buf.String()))
    23  }
    24  
    25  func TestWriteHumanReadablePrimitiveValues(t *testing.T) {
    26  	assertWriteHRSEqual(t, "true", Bool(true))
    27  	assertWriteHRSEqual(t, "false", Bool(false))
    28  
    29  	assertWriteHRSEqual(t, "0", Number(0))
    30  	assertWriteHRSEqual(t, "42", Number(42))
    31  
    32  	assertWriteHRSEqual(t, "-42", Number(-42))
    33  
    34  	assertWriteHRSEqual(t, "3.1415926535", Number(3.1415926535))
    35  	assertWriteHRSEqual(t, "314159.26535", Number(3.1415926535e5))
    36  	assertWriteHRSEqual(t, "3.1415926535e+20", Number(3.1415926535e20))
    37  
    38  	assertWriteHRSEqual(t, `"abc"`, String("abc"))
    39  	assertWriteHRSEqual(t, `" "`, String(" "))
    40  	assertWriteHRSEqual(t, `"\t"`, String("\t"))
    41  	assertWriteHRSEqual(t, `"\t"`, String("	"))
    42  	assertWriteHRSEqual(t, `"\n"`, String("\n"))
    43  	assertWriteHRSEqual(t, `"\n"`, String(`
    44  `))
    45  	assertWriteHRSEqual(t, `"\r"`, String("\r"))
    46  	assertWriteHRSEqual(t, `"\r\n"`, String("\r\n"))
    47  	assertWriteHRSEqual(t, `"\xff"`, String("\xff"))
    48  	assertWriteHRSEqual(t, `"💩"`, String("\xf0\x9f\x92\xa9"))
    49  	assertWriteHRSEqual(t, `"💩"`, String("💩"))
    50  	assertWriteHRSEqual(t, `"\a"`, String("\007"))
    51  	assertWriteHRSEqual(t, `"☺"`, String("\u263a"))
    52  }
    53  
    54  func TestWriteHumanReadableRef(t *testing.T) {
    55  	vs := newTestValueStore()
    56  
    57  	x := Number(42)
    58  	rv := vs.WriteValue(x)
    59  	assertWriteHRSEqual(t, "#0123456789abcdefghijklmnopqrstuv", rv)
    60  }
    61  
    62  func TestWriteHumanReadableCollections(t *testing.T) {
    63  	vrw := newTestValueStore()
    64  
    65  	l := NewList(vrw, Number(0), Number(1), Number(2), Number(3))
    66  	assertWriteHRSEqual(t, "[  // 4 items\n  0,\n  1,\n  2,\n  3,\n]", l)
    67  
    68  	s := NewSet(vrw, Number(0), Number(1), Number(2), Number(3))
    69  	assertWriteHRSEqual(t, "set {  // 4 items\n  0,\n  1,\n  2,\n  3,\n}", s)
    70  
    71  	m := NewMap(vrw, Number(0), Bool(false), Number(1), Bool(true))
    72  	assertWriteHRSEqual(t, "map {\n  0: false,\n  1: true,\n}", m)
    73  
    74  	l2 := NewList(vrw)
    75  	assertWriteHRSEqual(t, "[]", l2)
    76  
    77  	l3 := NewList(vrw, Number(0))
    78  	assertWriteHRSEqual(t, "[\n  0,\n]", l3)
    79  
    80  	nums := make([]Value, 2000)
    81  	for i := range nums {
    82  		nums[i] = Number(0)
    83  	}
    84  	l4 := NewList(vrw, nums...)
    85  	assertWriteHRSEqual(t, "[  // 2,000 items\n"+strings.Repeat("  0,\n", 2000)+"]", l4)
    86  }
    87  
    88  func TestWriteHumanReadableNested(t *testing.T) {
    89  	vrw := newTestValueStore()
    90  
    91  	l := NewList(vrw, Number(0), Number(1))
    92  	l2 := NewList(vrw, Number(2), Number(3))
    93  
    94  	s := NewSet(vrw, String("a"), String("b"))
    95  	s2 := NewSet(vrw, String("c"), String("d"))
    96  
    97  	m := NewMap(vrw, s, l, s2, l2)
    98  	assertWriteHRSEqual(t, `map {
    99    set {
   100      "c",
   101      "d",
   102    }: [
   103      2,
   104      3,
   105    ],
   106    set {
   107      "a",
   108      "b",
   109    }: [
   110      0,
   111      1,
   112    ],
   113  }`, m)
   114  }
   115  
   116  func TestWriteHumanReadableStruct(t *testing.T) {
   117  	str := NewStruct("S1", StructData{
   118  		"x": Number(1),
   119  		"y": Number(2),
   120  	})
   121  	assertWriteHRSEqual(t, "struct S1 {\n  x: 1,\n  y: 2,\n}", str)
   122  }
   123  
   124  func TestWriteHumanReadableListOfStruct(t *testing.T) {
   125  	vrw := newTestValueStore()
   126  
   127  	str1 := NewStruct("S3", StructData{
   128  		"x": Number(1),
   129  	})
   130  	str2 := NewStruct("S3", StructData{
   131  		"x": Number(2),
   132  	})
   133  	str3 := NewStruct("S3", StructData{
   134  		"x": Number(3),
   135  	})
   136  	l := NewList(vrw, str1, str2, str3)
   137  	assertWriteHRSEqual(t, `[
   138    struct S3 {
   139      x: 1,
   140    },
   141    struct S3 {
   142      x: 2,
   143    },
   144    struct S3 {
   145      x: 3,
   146    },
   147  ]`, l)
   148  }
   149  
   150  func TestWriteHumanReadableBlob(t *testing.T) {
   151  	vrw := newTestValueStore()
   152  	assertWriteHRSEqual(t, "blob {}", NewEmptyBlob(vrw))
   153  
   154  	b1 := NewBlob(vrw, bytes.NewBuffer([]byte{0x01}))
   155  	assertWriteHRSEqual(t, "blob {01}", b1)
   156  
   157  	b2 := NewBlob(vrw, bytes.NewBuffer([]byte{0x01, 0x02}))
   158  	assertWriteHRSEqual(t, "blob {01 02}", b2)
   159  
   160  	b3 := NewBlob(vrw, bytes.NewBuffer([]byte{
   161  		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   162  		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   163  	}))
   164  	assertWriteHRSEqual(t, "blob {00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f}", b3)
   165  
   166  	b4 := NewBlob(vrw, bytes.NewBuffer([]byte{
   167  		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   168  		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   169  		0x10,
   170  	}))
   171  	assertWriteHRSEqual(t, "blob {  // 17 B\n  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n  10\n}", b4)
   172  
   173  	bs := make([]byte, 256)
   174  	for i := range bs {
   175  		bs[i] = byte(i)
   176  	}
   177  
   178  	b5 := NewBlob(vrw, bytes.NewBuffer(bs))
   179  	assertWriteHRSEqual(t, "blob {  // 256 B\n  00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n  10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f\n  20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f\n  30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f\n  40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f\n  50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f\n  60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f\n  70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f\n  80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f\n  90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f\n  a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af\n  b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf\n  c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf\n  d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df\n  e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef\n  f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff\n}", b5)
   180  
   181  	b6 := NewBlob(vrw, bytes.NewBuffer(make([]byte, 16*100)))
   182  	row := "  " + strings.Repeat("00 ", 15) + "00\n"
   183  	s := strings.Repeat(row, 100)
   184  	assertWriteHRSEqual(t, "blob {  // 1.6 kB\n"+s+"}", b6)
   185  }
   186  
   187  func TestWriteHumanReadableListOfBlob(t *testing.T) {
   188  	vrw := newTestValueStore()
   189  
   190  	b1 := NewBlob(vrw, bytes.NewBuffer([]byte{0x01}))
   191  	b2 := NewBlob(vrw, bytes.NewBuffer([]byte{0x02}))
   192  	b3 := NewBlob(vrw, bytes.NewBuffer([]byte{
   193  		0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
   194  		0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
   195  		0x10,
   196  	}))
   197  	l := NewList(vrw, b1, NewEmptyBlob(vrw), b2, b3)
   198  	assertWriteHRSEqual(t, "[  // 4 items\n  blob {01},\n  blob {},\n  blob {02},\n  blob {  // 17 B\n    00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n    10\n  },\n]", l)
   199  }
   200  
   201  func TestWriteHumanReadableType(t *testing.T) {
   202  	assertWriteHRSEqual(t, "Bool", BoolType)
   203  	assertWriteHRSEqual(t, "Blob", BlobType)
   204  	assertWriteHRSEqual(t, "String", StringType)
   205  	assertWriteHRSEqual(t, "Number", NumberType)
   206  
   207  	assertWriteHRSEqual(t, "List<Number>", MakeListType(NumberType))
   208  	assertWriteHRSEqual(t, "Set<Number>", MakeSetType(NumberType))
   209  	assertWriteHRSEqual(t, "Ref<Number>", MakeRefType(NumberType))
   210  	assertWriteHRSEqual(t, "Map<Number, String>", MakeMapType(NumberType, StringType))
   211  	assertWriteHRSEqual(t, "Number | String", MakeUnionType(NumberType, StringType))
   212  	assertWriteHRSEqual(t, "Bool", MakeUnionType(BoolType))
   213  	assertWriteHRSEqual(t, "", MakeUnionType())
   214  	assertWriteHRSEqual(t, "List<Number | String>", MakeListType(MakeUnionType(NumberType, StringType)))
   215  	assertWriteHRSEqual(t, "List<>", MakeListType(MakeUnionType()))
   216  }
   217  
   218  func TestRecursiveStruct(t *testing.T) {
   219  	// struct A {
   220  	//   b: A
   221  	//   c: List<A>
   222  	//   d: struct D {
   223  	//     e: D
   224  	//     f: A
   225  	//   }
   226  	// }
   227  
   228  	a := MakeStructType("A",
   229  		StructField{"b", MakeCycleType("A"), false},
   230  		StructField{"c", MakeListType(MakeCycleType("A")), false},
   231  		StructField{"d", MakeStructType("D",
   232  			StructField{"e", MakeCycleType("D"), false},
   233  			StructField{"f", MakeCycleType("A"), false},
   234  		), false},
   235  	)
   236  
   237  	assertWriteHRSEqual(t, `Struct A {
   238    b: Cycle<A>,
   239    c: List<Cycle<A>>,
   240    d: Struct D {
   241      e: Cycle<D>,
   242      f: Cycle<A>,
   243    },
   244  }`, a)
   245  
   246  	d, _ := a.Desc.(StructDesc).Field("d")
   247  
   248  	assertWriteHRSEqual(t, `Struct D {
   249    e: Cycle<D>,
   250    f: Struct A {
   251      b: Cycle<A>,
   252      c: List<Cycle<A>>,
   253      d: Cycle<D>,
   254    },
   255  }`, d)
   256  }
   257  
   258  func TestUnresolvedRecursiveStruct(t *testing.T) {
   259  	// struct A {
   260  	//   a: A
   261  	//   b: Cycle<1> (unresolved)
   262  	// }
   263  	a := MakeStructType("A",
   264  		StructField{"a", MakeCycleType("A"), false},
   265  		StructField{"b", MakeCycleType("X"), false},
   266  	)
   267  
   268  	assertWriteHRSEqual(t, `Struct A {
   269    a: Cycle<A>,
   270    b: UnresolvedCycle<X>,
   271  }`, a)
   272  }
   273  
   274  type errorWriter struct {
   275  	err error
   276  }
   277  
   278  func (w *errorWriter) Write(p []byte) (int, error) {
   279  	return 0, w.err
   280  }
   281  
   282  func TestWriteHumanReadableWriterError(t *testing.T) {
   283  	assert := assert.New(t)
   284  	err := errors.New("test")
   285  	w := &errorWriter{err}
   286  	assert.Equal(err, WriteEncodedValue(w, Number(42)))
   287  }
   288  
   289  func TestEmptyCollections(t *testing.T) {
   290  	vrw := newTestValueStore()
   291  
   292  	a := MakeStructType("Nothing")
   293  	assertWriteHRSEqual(t, "Struct Nothing {}", a)
   294  	b := NewStruct("Rien", StructData{})
   295  	assertWriteHRSEqual(t, "struct Rien {}", b)
   296  	c := MakeMapType(BlobType, NumberType)
   297  	assertWriteHRSEqual(t, "Map<Blob, Number>", c)
   298  	d := NewMap(vrw)
   299  	assertWriteHRSEqual(t, "map {}", d)
   300  	e := MakeSetType(StringType)
   301  	assertWriteHRSEqual(t, "Set<String>", e)
   302  	f := NewSet(vrw)
   303  	assertWriteHRSEqual(t, "set {}", f)
   304  }
   305  
   306  func TestEncodedValueMaxLines(t *testing.T) {
   307  	assert := assert.New(t)
   308  	vrw := newTestValueStore()
   309  
   310  	l1 := NewList(vrw, generateNumbersAsValues(11)...)
   311  	expected := strings.Join(strings.SplitAfterN(EncodedValue(l1), "\n", 6)[:5], "")
   312  	assert.Equal(expected, EncodedValueMaxLines(l1, 5))
   313  
   314  	buf := bytes.Buffer{}
   315  	WriteEncodedValueMaxLines(&buf, l1, 5)
   316  	assert.Equal(expected, buf.String())
   317  }
   318  
   319  func TestWriteHumanReadableStructOptionalFields(t *testing.T) {
   320  	typ := MakeStructType("S1",
   321  		StructField{"a", BoolType, false},
   322  		StructField{"b", BoolType, true})
   323  	assertWriteHRSEqual(t, "Struct S1 {\n  a: Bool,\n  b?: Bool,\n}", typ)
   324  }
   325  
   326  type TestCommenter struct {
   327  	prefix   string
   328  	testType *Type
   329  }
   330  
   331  func (c TestCommenter) Comment(v Value) string {
   332  	if !(v.typeOf().Equals(c.testType)) {
   333  		return ""
   334  	}
   335  	return c.prefix + string(v.(Struct).Get("Name").(String))
   336  }
   337  
   338  func TestRegisterCommenter(t *testing.T) {
   339  	a := assert.New(t)
   340  
   341  	tt := NewStruct("TestType1", StructData{"Name": String("abc-123")})
   342  	nt := NewStruct("TestType2", StructData{"Name": String("abc-123")})
   343  
   344  	RegisterHRSCommenter("TestType1", "mylib1", TestCommenter{prefix: "MyTest: ", testType: tt.typeOf()})
   345  
   346  	s1 := EncodedValue(tt)
   347  	a.True(strings.Contains(s1, "// MyTest: abc-123"))
   348  	s1 = EncodedValue(nt)
   349  	a.False(strings.Contains(s1, "// MyTest: abc-123"))
   350  
   351  	RegisterHRSCommenter("TestType1", "mylib1", TestCommenter{prefix: "MyTest2: ", testType: tt.typeOf()})
   352  	s1 = EncodedValue(tt)
   353  	a.True(strings.Contains(s1, "// MyTest2: abc-123"))
   354  
   355  	UnregisterHRSCommenter("TestType1", "mylib1")
   356  	s1 = EncodedValue(tt)
   357  	a.False(strings.Contains(s1, "// MyTest2: abc-123"))
   358  }