cuelang.org/go@v0.10.1/internal/third_party/yaml/decode_test.go (about)

     1  package yaml_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  
    12  	"cuelang.org/go/cue/ast"
    13  	"cuelang.org/go/cue/format"
    14  	"cuelang.org/go/internal/cuetest"
    15  	"cuelang.org/go/internal/third_party/yaml"
    16  )
    17  
    18  var unmarshalIntTest = 123
    19  
    20  var unmarshalTests = []struct {
    21  	data string
    22  	want string
    23  }{
    24  	{
    25  		"",
    26  		"",
    27  	},
    28  	{
    29  		"{}",
    30  		"",
    31  	}, {
    32  		"v: hi",
    33  		`v: "hi"`,
    34  	}, {
    35  		"v: hi",
    36  		`v: "hi"`,
    37  	}, {
    38  		"v: true",
    39  		"v: true",
    40  	}, {
    41  		"v: 10",
    42  		"v: 10",
    43  	}, {
    44  		"v: 0b10",
    45  		"v: 0b10",
    46  	}, {
    47  		"v: 0xA",
    48  		"v: 0xA",
    49  	}, {
    50  		"v: 4294967296",
    51  		"v: 4294967296",
    52  	}, {
    53  		"v: 0.1",
    54  		"v: 0.1",
    55  	}, {
    56  		"v: .1",
    57  		"v: 0.1",
    58  	}, {
    59  		"v: .Inf",
    60  		"v: +Inf",
    61  	}, {
    62  		"v: -.Inf",
    63  		"v: -Inf",
    64  	}, {
    65  		"v: -10",
    66  		"v: -10",
    67  	}, {
    68  		"v: -.1",
    69  		"v: -0.1",
    70  	},
    71  
    72  	// Simple values.
    73  	{
    74  		"123",
    75  		"123",
    76  	},
    77  
    78  	// Floats from spec
    79  	{
    80  		"canonical: 6.8523e+5",
    81  		"canonical: 6.8523e+5",
    82  	}, {
    83  		"expo: 685.230_15e+03",
    84  		"expo: 685.230_15e+03",
    85  	}, {
    86  		"fixed: 685_230.15",
    87  		"fixed: 685_230.15",
    88  	}, {
    89  		"neginf: -.inf",
    90  		"neginf: -Inf",
    91  	}, {
    92  		"fixed: 685_230.15",
    93  		"fixed: 685_230.15",
    94  	},
    95  	//{"sexa: 190:20:30.15", map[string]interface{}{"sexa": 0}}, // Unsupported
    96  	//{"notanum: .NaN", map[string]interface{}{"notanum": math.NaN()}}, // Equality of NaN fails.
    97  
    98  	// Bools from spec
    99  	{
   100  		"canonical: y",
   101  		`canonical: "y"`,
   102  	}, {
   103  		"answer: n",
   104  		`answer: "n"`,
   105  	}, {
   106  		"answer: NO",
   107  		`answer: "NO"`,
   108  	}, {
   109  		"logical: True",
   110  		"logical: true",
   111  	}, {
   112  		"option: on",
   113  		`option: "on"`,
   114  	}, {
   115  		"answer: off",
   116  		`answer: "off"`,
   117  	},
   118  	// Ints from spec
   119  	{
   120  		"canonical: 685230",
   121  		"canonical: 685230",
   122  	}, {
   123  		"decimal: +685_230",
   124  		"decimal: +685_230",
   125  	}, {
   126  		"octal: 02472256",
   127  		"octal: 0o2472256",
   128  	}, {
   129  		"hexa: 0x_0A_74_AE",
   130  		"hexa: 0x_0A_74_AE",
   131  	}, {
   132  		"bin: 0b1010_0111_0100_1010_1110",
   133  		"bin: 0b1010_0111_0100_1010_1110",
   134  	}, {
   135  		"bin: -0b101010",
   136  		"bin: -0b101010",
   137  	}, {
   138  		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
   139  		"bin: -0b1000000000000000000000000000000000000000000000000000000000000000",
   140  	}, {
   141  		"decimal: +685_230",
   142  		"decimal: +685_230",
   143  	},
   144  
   145  	//{"sexa: 190:20:30", map[string]interface{}{"sexa": 0}}, // Unsupported
   146  
   147  	// Nulls from spec
   148  	{
   149  		"empty:",
   150  		"empty: null",
   151  	}, {
   152  		"canonical: ~",
   153  		"canonical: null",
   154  	}, {
   155  		"english: null",
   156  		"english: null",
   157  	}, {
   158  		"_foo: 1",
   159  		`"_foo": 1`,
   160  	}, {
   161  		`"#foo": 1`,
   162  		`"#foo": 1`,
   163  	}, {
   164  		"_#foo: 1",
   165  		`"_#foo": 1`,
   166  	}, {
   167  		"~: null key",
   168  		`"null": "null key"`,
   169  	}, {
   170  		`empty:
   171  apple: "newline"`,
   172  		`empty: null
   173  apple: "newline"`,
   174  	},
   175  
   176  	// Flow sequence
   177  	{
   178  		"seq: [A,B]",
   179  		`seq: ["A", "B"]`,
   180  	}, {
   181  		"seq: [A,B,C,]",
   182  		`seq: ["A", "B", "C"]`,
   183  	}, {
   184  		"seq: [A,1,C]",
   185  		`seq: ["A", 1, "C"]`,
   186  	},
   187  	// Block sequence
   188  	{
   189  		"seq:\n - A\n - B",
   190  		`seq: [
   191  	"A",
   192  	"B",
   193  ]`,
   194  	}, {
   195  		"seq:\n - A\n - B\n - C",
   196  		`seq: [
   197  	"A",
   198  	"B",
   199  	"C",
   200  ]`,
   201  	}, {
   202  		"seq:\n - A\n - 1\n - C",
   203  		`seq: [
   204  	"A",
   205  	1,
   206  	"C",
   207  ]`,
   208  	},
   209  
   210  	// Literal block scalar
   211  	{
   212  		"scalar: | # Comment\n\n literal\n\n \ttext\n\n",
   213  		`scalar: """
   214  
   215  	literal
   216  
   217  	\ttext
   218  
   219  	"""`,
   220  	},
   221  
   222  	// Folded block scalar
   223  	{
   224  		"scalar: > # Comment\n\n folded\n line\n \n next\n line\n  * one\n  * two\n\n last\n line\n\n",
   225  		`scalar: """
   226  
   227  	folded line
   228  	next line
   229  	 * one
   230  	 * two
   231  
   232  	last line
   233  
   234  	"""`,
   235  	},
   236  
   237  	// Structs
   238  	{
   239  		"a: {b: c}",
   240  		`a: {b: "c"}`,
   241  	},
   242  	{
   243  		"hello: world",
   244  		`hello: "world"`,
   245  	}, {
   246  		"a:",
   247  		"a: null",
   248  	}, {
   249  		"a: 1",
   250  		"a: 1",
   251  	}, {
   252  		"a: 1.0",
   253  		"a: 1.0",
   254  	}, {
   255  		"a: [1, 2]",
   256  		"a: [1, 2]",
   257  	}, {
   258  		"a: y",
   259  		`a: "y"`,
   260  	}, {
   261  		"{ a: 1, b: {c: 1} }",
   262  		`a: 1, b: {c: 1}`,
   263  	}, {
   264  		`
   265  True: 1
   266  Null: 1
   267  .Inf: 2
   268  `,
   269  		`"true": 1
   270  "null": 1
   271  "+Inf": 2`,
   272  	},
   273  
   274  	// Some cross type conversions
   275  	{
   276  		"v: 42",
   277  		"v: 42",
   278  	}, {
   279  		"v: -42",
   280  		"v: -42",
   281  	}, {
   282  		"v: 4294967296",
   283  		"v: 4294967296",
   284  	}, {
   285  		"v: -4294967296",
   286  		"v: -4294967296",
   287  	},
   288  
   289  	// int
   290  	{
   291  		"int_max: 2147483647",
   292  		"int_max: 2147483647",
   293  	},
   294  	{
   295  		"int_min: -2147483648",
   296  		"int_min: -2147483648",
   297  	},
   298  	{
   299  		"int_overflow: 9223372036854775808", // math.MaxInt64 + 1
   300  		"int_overflow: 9223372036854775808", // math.MaxInt64 + 1
   301  	},
   302  
   303  	// int64
   304  	{
   305  		"int64_max: 9223372036854775807",
   306  		"int64_max: 9223372036854775807",
   307  	},
   308  	{
   309  		"int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
   310  		"int64_max_base2: 0b111111111111111111111111111111111111111111111111111111111111111",
   311  	},
   312  	{
   313  		"int64_min: -9223372036854775808",
   314  		"int64_min: -9223372036854775808",
   315  	},
   316  	{
   317  		"int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
   318  		"int64_neg_base2: -0b111111111111111111111111111111111111111111111111111111111111111",
   319  	},
   320  	{
   321  		"int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
   322  		"int64_overflow: 9223372036854775808", // math.MaxInt64 + 1
   323  	},
   324  
   325  	// uint
   326  	{
   327  		"uint_max: 4294967295",
   328  		"uint_max: 4294967295",
   329  	},
   330  
   331  	// uint64
   332  	{
   333  		"uint64_max: 18446744073709551615",
   334  		"uint64_max: 18446744073709551615",
   335  	},
   336  	{
   337  		"uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
   338  		"uint64_max_base2: 0b1111111111111111111111111111111111111111111111111111111111111111",
   339  	},
   340  	{
   341  		"uint64_maxint64: 9223372036854775807",
   342  		"uint64_maxint64: 9223372036854775807",
   343  	},
   344  
   345  	// float32
   346  	{
   347  		"float32_max: 3.40282346638528859811704183484516925440e+38",
   348  		"float32_max: 3.40282346638528859811704183484516925440e+38",
   349  	},
   350  	{
   351  		"float32_nonzero: 1.401298464324817070923729583289916131280e-45",
   352  		"float32_nonzero: 1.401298464324817070923729583289916131280e-45",
   353  	},
   354  	{
   355  		"float32_maxuint64: 18446744073709551615",
   356  		"float32_maxuint64: 18446744073709551615",
   357  	},
   358  	{
   359  		"float32_maxuint64+1: 18446744073709551616",
   360  		`"float32_maxuint64+1": 18446744073709551616`,
   361  	},
   362  
   363  	// float64
   364  	{
   365  		"float64_max: 1.797693134862315708145274237317043567981e+308",
   366  		"float64_max: 1.797693134862315708145274237317043567981e+308",
   367  	},
   368  	{
   369  		"float64_nonzero: 4.940656458412465441765687928682213723651e-324",
   370  		"float64_nonzero: 4.940656458412465441765687928682213723651e-324",
   371  	},
   372  	{
   373  		"float64_maxuint64: 18446744073709551615",
   374  		"float64_maxuint64: 18446744073709551615",
   375  	},
   376  	{
   377  		"float64_maxuint64+1: 18446744073709551616",
   378  		`"float64_maxuint64+1": 18446744073709551616`,
   379  	},
   380  
   381  	// Overflow cases.
   382  	{
   383  		"v: 4294967297",
   384  		"v: 4294967297",
   385  	}, {
   386  		"v: 128",
   387  		"v: 128",
   388  	},
   389  
   390  	// Quoted values.
   391  	{
   392  		"'1': '\"2\"'",
   393  		`"1": "\"2\""`,
   394  	}, {
   395  		"v:\n- A\n- 'B\n\n  C'\n",
   396  		`v: [
   397  	"A",
   398  	"""
   399  		B
   400  		C
   401  		""",
   402  ]`,
   403  	}, {
   404  		`"\0"`,
   405  		`"\u0000"`,
   406  	},
   407  
   408  	// Explicit tags.
   409  	{
   410  		"v: !!float '1.1'",
   411  		"v: 1.1",
   412  	}, {
   413  		"v: !!float 0",
   414  		"v: float & 0", // Should this be 0.0?
   415  	}, {
   416  		"v: !!float -1",
   417  		"v: float & -1", // Should this be -1.0?
   418  	}, {
   419  		"v: !!null ''",
   420  		"v: null",
   421  	}, {
   422  		"%TAG !y! tag:yaml.org,2002:\n---\nv: !y!int '1'",
   423  		"v: 1",
   424  	},
   425  
   426  	// Non-specific tag (Issue #75)
   427  	{
   428  		`v: ! test`,
   429  		// TODO this should work and produce a string.
   430  		"",
   431  	},
   432  
   433  	// Anchors and aliases.
   434  	{
   435  		"a: &x 1\nb: &y 2\nc: *x\nd: *y\n",
   436  		`a: 1
   437  b: 2
   438  c: 1
   439  d: 2`,
   440  	}, {
   441  		"a: &a {c: 1}\nb: *a",
   442  		`a: {c: 1}
   443  b: {
   444  	c: 1
   445  }`,
   446  	}, {
   447  		"a: &a [1, 2]\nb: *a",
   448  		"a: [1, 2]\nb: [1, 2]", // TODO: a: [1, 2], b: a
   449  	},
   450  
   451  	{
   452  		"foo: ''",
   453  		`foo: ""`,
   454  	}, {
   455  		"foo: null",
   456  		"foo: null",
   457  	},
   458  
   459  	// Support for ~
   460  	{
   461  		"foo: ~",
   462  		"foo: null",
   463  	},
   464  
   465  	// Bug #1191981
   466  	{
   467  		"" +
   468  			"%YAML 1.1\n" +
   469  			"--- !!str\n" +
   470  			`"Generic line break (no glyph)\n\` + "\n" +
   471  			` Generic line break (glyphed)\n\` + "\n" +
   472  			` Line separator\u2028\` + "\n" +
   473  			` Paragraph separator\u2029"` + "\n",
   474  		`"""
   475  	Generic line break (no glyph)
   476  	Generic line break (glyphed)
   477  	Line separator\u2028Paragraph separator\u2029
   478  	"""`,
   479  	},
   480  
   481  	// bug 1243827
   482  	{
   483  		"a: -b_c",
   484  		`a: "-b_c"`,
   485  	},
   486  	{
   487  		"a: +b_c",
   488  		`a: "+b_c"`,
   489  	},
   490  	{
   491  		"a: 50cent_of_dollar",
   492  		`a: "50cent_of_dollar"`,
   493  	},
   494  
   495  	// issue #295 (allow scalars with colons in flow mappings and sequences)
   496  	{
   497  		"a: {b: https://github.com/go-yaml/yaml}",
   498  		`a: {b: "https://github.com/go-yaml/yaml"}`,
   499  	},
   500  	{
   501  		"a: [https://github.com/go-yaml/yaml]",
   502  		`a: ["https://github.com/go-yaml/yaml"]`,
   503  	},
   504  
   505  	// Duration
   506  	{
   507  		"a: 3s",
   508  		`a: "3s"`, // for now
   509  	},
   510  
   511  	// Issue #24.
   512  	{
   513  		"a: <foo>",
   514  		`a: "<foo>"`,
   515  	},
   516  
   517  	// Base 60 floats are obsolete and unsupported.
   518  	{
   519  		"a: 1:1\n",
   520  		`a: "1:1"`,
   521  	},
   522  
   523  	// Binary data.
   524  	{
   525  		"a: !!binary gIGC\n",
   526  		`a: '\x80\x81\x82'`,
   527  	}, {
   528  		"a: !!binary |\n  " + strings.Repeat("kJCQ", 17) + "kJ\n  CQ\n",
   529  		"a: '" + strings.Repeat(`\x90`, 54) + "'",
   530  	}, {
   531  		"a: !!binary |\n  " + strings.Repeat("A", 70) + "\n  ==\n",
   532  		"a: '" + strings.Repeat(`\x00`, 52) + "'",
   533  	},
   534  
   535  	// Ordered maps.
   536  	{
   537  		"{b: 2, a: 1, d: 4, c: 3, sub: {e: 5}}",
   538  		`b: 2, a: 1, d: 4, c: 3, sub: {e: 5}`,
   539  	},
   540  
   541  	// Spacing
   542  	{
   543  		`
   544  a: {}
   545  c: 1
   546  d: []
   547  e: []
   548  `,
   549  		`a: {}
   550  c: 1
   551  d: []
   552  e: []`,
   553  	},
   554  
   555  	{
   556  		`
   557  a:
   558    - { "a": 1, "b": 2 }
   559    - { "c": 1, "d": 2 }
   560  `,
   561  		`a: [{
   562  	a: 1, b: 2
   563  }, {
   564  	c: 1, d: 2
   565  }]`,
   566  	},
   567  
   568  	{
   569  		"a:\n b:\n  c: d\n  e: f\n",
   570  		`a: {
   571  	b: {
   572  		c: "d"
   573  		e: "f"
   574  	}
   575  }`,
   576  	},
   577  
   578  	// Issue #39.
   579  	{
   580  		"a:\n b:\n  c: d\n",
   581  		`a: {
   582  	b: {
   583  		c: "d"
   584  	}
   585  }`,
   586  	},
   587  
   588  	// Timestamps
   589  	{
   590  		// Date only.
   591  		"a: 2015-01-01\n",
   592  		`a: "2015-01-01"`,
   593  	},
   594  	{
   595  		// RFC3339
   596  		"a: 2015-02-24T18:19:39.12Z\n",
   597  		`a: "2015-02-24T18:19:39.12Z"`,
   598  	},
   599  	{
   600  		// RFC3339 with short dates.
   601  		"a: 2015-2-3T3:4:5Z",
   602  		`a: "2015-2-3T3:4:5Z"`,
   603  	},
   604  	{
   605  		// ISO8601 lower case t
   606  		"a: 2015-02-24t18:19:39Z\n",
   607  		`a: "2015-02-24t18:19:39Z"`,
   608  	},
   609  	{
   610  		// space separate, no time zone
   611  		"a: 2015-02-24 18:19:39\n",
   612  		`a: "2015-02-24 18:19:39"`,
   613  	},
   614  	// Some cases not currently handled. Uncomment these when
   615  	// the code is fixed.
   616  	//	{
   617  	//		// space separated with time zone
   618  	//		"a: 2001-12-14 21:59:43.10 -5",
   619  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   620  	//	},
   621  	//	{
   622  	//		// arbitrary whitespace between fields
   623  	//		"a: 2001-12-14 \t\t \t21:59:43.10 \t Z",
   624  	//		map[string]interface{}{"a": time.Date(2001, 12, 14, 21, 59, 43, .1e9, time.UTC)},
   625  	//	},
   626  	{
   627  		// explicit string tag
   628  		"a: !!str 2015-01-01",
   629  		`a: "2015-01-01"`,
   630  	},
   631  	{
   632  		// explicit timestamp tag on quoted string
   633  		"a: !!timestamp \"2015-01-01\"",
   634  		`a: "2015-01-01"`,
   635  	},
   636  	{
   637  		// explicit timestamp tag on unquoted string
   638  		"a: !!timestamp 2015-01-01",
   639  		`a: "2015-01-01"`,
   640  	},
   641  	{
   642  		// quoted string that's a valid timestamp
   643  		"a: \"2015-01-01\"",
   644  		"a: \"2015-01-01\"",
   645  	},
   646  
   647  	// Empty list
   648  	{
   649  		"a: []",
   650  		"a: []",
   651  	},
   652  
   653  	// UTF-16-LE
   654  	{
   655  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n\x00",
   656  		`ñoño: "very yes"`,
   657  	},
   658  	// UTF-16-LE with surrogate.
   659  	{
   660  		"\xff\xfe\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \x00=\xd8\xd4\xdf\n\x00",
   661  		`ñoño: "very yes 🟔"`,
   662  	},
   663  
   664  	// UTF-16-BE
   665  	{
   666  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00\n",
   667  		`ñoño: "very yes"`,
   668  	},
   669  	// UTF-16-BE with surrogate.
   670  	{
   671  		"\xfe\xff\x00\xf1\x00o\x00\xf1\x00o\x00:\x00 \x00v\x00e\x00r\x00y\x00 \x00y\x00e\x00s\x00 \xd8=\xdf\xd4\x00\n",
   672  		`ñoño: "very yes 🟔"`,
   673  	},
   674  
   675  	// This *is* in fact a float number, per the spec. #171 was a mistake.
   676  	{
   677  		"a: 123456e1\n",
   678  		`a: 123456e1`,
   679  	}, {
   680  		"a: 123456E1\n",
   681  		`a: 123456e1`,
   682  	},
   683  	// Other float formats:
   684  	{
   685  		"x: .1",
   686  		"x: 0.1",
   687  	},
   688  	{
   689  		"x: .1e-3",
   690  		"x: 0.1e-3",
   691  	},
   692  	{
   693  		"x: 1.2E4",
   694  		"x: 1.2e4",
   695  	},
   696  	{
   697  		"x: 1.2E+4",
   698  		"x: 1.2e+4",
   699  	},
   700  	// yaml-test-suite 3GZX: Spec Example 7.1. Alias Nodes
   701  	{
   702  		"First occurrence: &anchor Foo\nSecond occurrence: *anchor\nOverride anchor: &anchor Bar\nReuse anchor: *anchor\n",
   703  		`"First occurrence":  "Foo"
   704  "Second occurrence": "Foo"
   705  "Override anchor":   "Bar"
   706  "Reuse anchor":      "Bar"`,
   707  	},
   708  	// Single document with garbage following it.
   709  	{
   710  		"---\nhello\n...\n}not yaml",
   711  		`"hello"`,
   712  	},
   713  }
   714  
   715  type M map[interface{}]interface{}
   716  
   717  type inlineB struct {
   718  	B       int
   719  	inlineC `yaml:",inline"`
   720  }
   721  
   722  type inlineC struct {
   723  	C int
   724  }
   725  
   726  func cueStr(node ast.Node) string {
   727  	if s, ok := node.(*ast.StructLit); ok {
   728  		node = &ast.File{
   729  			Decls: s.Elts,
   730  		}
   731  	}
   732  	b, _ := format.Node(node)
   733  	return strings.TrimSpace(string(b))
   734  }
   735  
   736  func newDecoder(t *testing.T, data string) *yaml.Decoder {
   737  	dec, err := yaml.NewDecoder("test.yaml", strings.NewReader(data))
   738  	if err != nil {
   739  		t.Fatal(err)
   740  	}
   741  	return dec
   742  }
   743  
   744  func callUnmarshal(t *testing.T, data string) (ast.Expr, error) {
   745  	return yaml.Unmarshal("test.yaml", []byte(data))
   746  }
   747  
   748  func TestUnmarshal(t *testing.T) {
   749  	for i, item := range unmarshalTests {
   750  		t.Run(strconv.Itoa(i), func(t *testing.T) {
   751  			t.Logf("test %d: %q", i, item.data)
   752  			expr, err := callUnmarshal(t, item.data)
   753  			if _, ok := err.(*yaml.TypeError); !ok && err != nil {
   754  				t.Fatal("expected error to be nil")
   755  			}
   756  			if got := cueStr(expr); got != item.want {
   757  				t.Errorf("\n got:\n%v\nwant:\n%v", got, item.want)
   758  			}
   759  		})
   760  	}
   761  }
   762  
   763  // For debug purposes: do not delete.
   764  func TestX(t *testing.T) {
   765  	y := `
   766  `
   767  	y = strings.TrimSpace(y)
   768  	if len(y) == 0 {
   769  		t.Skip()
   770  	}
   771  
   772  	expr, err := callUnmarshal(t, y)
   773  	if _, ok := err.(*yaml.TypeError); !ok && err != nil {
   774  		t.Fatal(err)
   775  	}
   776  	t.Error(cueStr(expr))
   777  }
   778  
   779  // // TODO(v3): This test should also work when unmarshaling onto an interface{}.
   780  // func (s *S) TestUnmarshalFullTimestamp(c *C) {
   781  // 	// Full timestamp in same format as encoded. This is confirmed to be
   782  // 	// properly decoded by Python as a timestamp as well.
   783  // 	var str = "2015-02-24T18:19:39.123456789-03:00"
   784  // 	expr, err := yaml.Unmarshal([]byte(str))
   785  // 	c.Assert(err, IsNil)
   786  // 	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location()))
   787  // 	c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
   788  // }
   789  
   790  func TestDecoderSingleDocument(t *testing.T) {
   791  	// Test that Decoder.Decode works as expected on
   792  	// all the unmarshal tests.
   793  	for i, item := range unmarshalTests {
   794  		t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) {
   795  			if item.data == "" {
   796  				// Behaviour differs when there's no YAML.
   797  				return
   798  			}
   799  			expr, err := newDecoder(t, item.data).Decode()
   800  			if _, ok := err.(*yaml.TypeError); !ok && err != nil {
   801  				t.Errorf("err should be nil, was %v", err)
   802  			}
   803  			if got := cueStr(expr); got != item.want {
   804  				t.Errorf("\n got: %v;\nwant: %v", got, item.want)
   805  			}
   806  		})
   807  	}
   808  }
   809  
   810  var decoderTests = []struct {
   811  	data string
   812  	want string
   813  }{{
   814  	"",
   815  	"",
   816  }, {
   817  	"a: b",
   818  	`a: "b"`,
   819  }, {
   820  	"---\na: b\n...\n",
   821  	`a: "b"`,
   822  }, {
   823  	"---\n'hello'\n...\n---\ngoodbye\n...\n",
   824  	`"hello"` + "\n" + `"goodbye"`,
   825  }}
   826  
   827  func TestDecoder(t *testing.T) {
   828  	for i, item := range decoderTests {
   829  		t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) {
   830  			var values []string
   831  			dec := newDecoder(t, item.data)
   832  			for {
   833  				expr, err := dec.Decode()
   834  				if err == io.EOF {
   835  					break
   836  				}
   837  				if err != nil {
   838  					t.Errorf("err should be nil, was %v", err)
   839  				}
   840  				values = append(values, cueStr(expr))
   841  			}
   842  			got := strings.Join(values, "\n")
   843  			if got != item.want {
   844  				t.Errorf("\n got: %v;\nwant: %v", got, item.want)
   845  			}
   846  		})
   847  	}
   848  }
   849  
   850  type errReader struct{}
   851  
   852  func (errReader) Read([]byte) (int, error) {
   853  	return 0, errors.New("some read error")
   854  }
   855  
   856  func TestUnmarshalNaN(t *testing.T) {
   857  	expr, err := callUnmarshal(t, "notanum: .NaN")
   858  	if err != nil {
   859  		t.Fatal("unexpected error", err)
   860  	}
   861  	got := cueStr(expr)
   862  	want := "notanum: NaN"
   863  	if got != want {
   864  		t.Errorf("got %v; want %v", got, want)
   865  	}
   866  }
   867  
   868  var unmarshalErrorTests = []struct {
   869  	data, error string
   870  }{
   871  	{"\nv: !!float 'error'", "test.yaml:2: cannot decode !!str `error` as a !!float"},
   872  	{"v: [A,", "test.yaml:1: did not find expected node content"},
   873  	{"v:\n- [A,", "test.yaml:2: did not find expected node content"},
   874  	{"a:\n- b: *,", "test.yaml:2: did not find expected alphabetic or numeric character"},
   875  	{"a: *b\n", "test.yaml:1: unknown anchor 'b' referenced"},
   876  	{"a: &a\n  b: *a\n", "test.yaml:2: anchor 'a' value contains itself"},
   877  	{"value: -", "test.yaml:1: block sequence entries are not allowed in this context"},
   878  	{"a: !!binary ==", "test.yaml:1: !!binary value contains invalid base64 data"},
   879  	{"{[.]}", `test.yaml:1: invalid map key: sequence`},
   880  	{"{{.}}", `test.yaml:1: invalid map key: map`},
   881  	{"b: *a\na: &a {c: 1}", `test.yaml:1: unknown anchor 'a' referenced`},
   882  	{"%TAG !%79! tag:yaml.org,2002:\n---\nv: !%79!int '1'", "test.yaml:1: did not find expected whitespace"},
   883  }
   884  
   885  func TestUnmarshalErrors(t *testing.T) {
   886  	for i, item := range unmarshalErrorTests {
   887  		t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) {
   888  			expr, err := callUnmarshal(t, item.data)
   889  			val := ""
   890  			if expr != nil {
   891  				val = cueStr(expr)
   892  			}
   893  			if err == nil || err.Error() != item.error {
   894  				t.Errorf("got %v; want %v; (value %v)", err, item.error, val)
   895  			}
   896  		})
   897  	}
   898  }
   899  
   900  func TestDecoderErrors(t *testing.T) {
   901  	for i, item := range unmarshalErrorTests {
   902  		t.Run(fmt.Sprintf("test %d: %q", i, item.data), func(t *testing.T) {
   903  			_, err := newDecoder(t, item.data).Decode()
   904  			if err == nil || err.Error() != item.error {
   905  				t.Errorf("got %v; want %v", err, item.error)
   906  			}
   907  		})
   908  	}
   909  }
   910  
   911  func TestFiles(t *testing.T) {
   912  	files := []string{"merge"}
   913  	for _, test := range files {
   914  		t.Run(test, func(t *testing.T) {
   915  			testname := fmt.Sprintf("testdata/%s.test", test)
   916  			filename := fmt.Sprintf("testdata/%s.out", test)
   917  			mergeTests, err := os.ReadFile(testname)
   918  			if err != nil {
   919  				t.Fatal(err)
   920  			}
   921  			expr, err := yaml.Unmarshal("test.yaml", mergeTests)
   922  			if err != nil {
   923  				t.Fatal(err)
   924  			}
   925  			got := cueStr(expr)
   926  			if cuetest.UpdateGoldenFiles {
   927  				os.WriteFile(filename, []byte(got), 0644)
   928  				return
   929  			}
   930  			b, err := os.ReadFile(filename)
   931  			if err != nil {
   932  				t.Fatal(err)
   933  			}
   934  			if want := string(b); got != want {
   935  				t.Errorf("\n got: %v;\nwant: %v", got, want)
   936  			}
   937  		})
   938  	}
   939  }
   940  
   941  func TestFuzzCrashers(t *testing.T) {
   942  	cases := []string{
   943  		// runtime error: index out of range
   944  		"\"\\0\\\r\n",
   945  
   946  		// should not happen
   947  		"  0: [\n] 0",
   948  		"? ? \"\n\" 0",
   949  		"    - {\n000}0",
   950  		"0:\n  0: [0\n] 0",
   951  		"    - \"\n000\"0",
   952  		"    - \"\n000\"\"",
   953  		"0:\n    - {\n000}0",
   954  		"0:\n    - \"\n000\"0",
   955  		"0:\n    - \"\n000\"\"",
   956  
   957  		// runtime error: index out of range
   958  		" \ufeff\n",
   959  		"? \ufeff\n",
   960  		"? \ufeff:\n",
   961  		"0: \ufeff\n",
   962  		"? \ufeff: \ufeff\n",
   963  	}
   964  	for _, data := range cases {
   965  		_, _ = callUnmarshal(t, data)
   966  	}
   967  }
   968  
   969  //var data []byte
   970  //func init() {
   971  //	var err error
   972  //	data, err = os.ReadFile("/tmp/file.yaml")
   973  //	if err != nil {
   974  //		panic(err)
   975  //	}
   976  //}
   977  //
   978  //func (s *S) BenchmarkUnmarshal(c *C) {
   979  //	var err error
   980  //	for i := 0; i < c.N; i++ {
   981  //		var v map[string]interface{}
   982  //		err = yaml.Unmarshal(data, &v)
   983  //	}
   984  //	if err != nil {
   985  //		panic(err)
   986  //	}
   987  //}
   988  //
   989  //func (s *S) BenchmarkMarshal(c *C) {
   990  //	var v map[string]interface{}
   991  //	yaml.Unmarshal(data, &v)
   992  //	c.ResetTimer()
   993  //	for i := 0; i < c.N; i++ {
   994  //		yaml.Marshal(&v)
   995  //	}
   996  //}