...

Source file src/cuelang.org/go/cue/literal/string_test.go

Documentation: cuelang.org/go/cue/literal

     1  // Copyright 2019 CUE Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package literal
    16  
    17  import (
    18  	"fmt"
    19  	"testing"
    20  )
    21  
    22  func TestUnquote(t *testing.T) {
    23  	testCases := []struct {
    24  		in, out string
    25  		err     error
    26  	}{
    27  		{`"Hello"`, "Hello", nil},
    28  		{`'Hello'`, "Hello", nil},
    29  		{`'Hellø'`, "Hellø", nil},
    30  		{`"""` + "\n\t\tHello\n\t\t" + `"""`, "Hello", nil},
    31  		{`"""` + "\r\n\tHello\r\n\n\t" + `"""`, "Hello\n", nil},
    32  		{"'''\n\t\tHello\n\t\t'''", "Hello", nil},
    33  		{`"""` + "\n\tHello \\\n\tworld\n\t" + `"""`, "Hello world", nil},
    34  		{`"""` + "\r\n\tHello \\\r\n\tworld\r\n\t" + `"""`, "Hello world", nil},
    35  		{`"""` + "\none \\\ntwo \\\nthree\n" + `"""`, "one two three", nil},
    36  		{`"""` + "\nHello\\\n" + `"""`, "", errEscapedLastNewline},
    37  		{`"""` + "\n\tHello\\\n\t" + `"""`, "", errEscapedLastNewline},
    38  		{`"""` + "\r\n\tHello\\\r\n\t" + `"""`, "", errEscapedLastNewline},
    39  		{"'''\n\t\tHello\n\n\t\t'''", "Hello\n", nil},
    40  		{"'''\n\n\t\tHello\n\t\t'''", "\nHello", nil},
    41  		{"'''\n\n\n\n\t\t'''", "\n\n", nil},
    42  		{"'''\n\t\t'''", "", nil},
    43  		{`"""` + "\n\raaa\n\rbbb\n\r" + `"""`, "aaa\nbbb", nil},
    44  		{`'\a\b\f\n\r\t\v\'\\\/'`, "\a\b\f\n\r\t\v'\\/", nil},
    45  		{`"\a\b\f\n\r\t\v\"\\\/"`, "\a\b\f\n\r\t\v\"\\/", nil},
    46  		{`#"The sequence "\U0001F604" renders as \#U0001F604."#`,
    47  			`The sequence "\U0001F604" renders as 😄.`,
    48  			nil},
    49  		{`"  \U00010FfF"`, "  \U00010fff", nil},
    50  		{`"\u0061 "`, "a ", nil},
    51  		{`'\x61\x55'`, "\x61\x55", nil},
    52  		{`'\061\055'`, "\061\055", nil},
    53  		{`'\377 '`, "\377 ", nil},
    54  		{"'e\u0300\\n'", "e\u0300\n", nil},
    55  		{`'\06\055'`, "", errSyntax},
    56  		{`'\0'`, "", errSyntax},
    57  		{`"\06\055"`, "", errSyntax},    // too short
    58  		{`'\777 '`, "", errSyntax},      // overflow
    59  		{`'\U012301'`, "", errSyntax},   // too short
    60  		{`'\U0123012G'`, "", errSyntax}, // invalid digit G
    61  		{`"\x04"`, "", errSyntax},       // not allowed in strings
    62  		{`'\U01230123'`, "", errSyntax}, // too large
    63  
    64  		// Surrogate pairs
    65  		{`"\uD834\uDD1E"`, "𝄞", nil},
    66  		{`"\uDD1E\uD834"`, "", errSurrogate},
    67  		{`"\uD834\uD834"`, "", errSurrogate},
    68  
    69  		{`"\\"`, "\\", nil},
    70  		{`"\'"`, "", errSyntax},
    71  		{`"\q"`, "", errSyntax},
    72  		{"'\n'", "", errSyntax},
    73  		{"'---\n---'", "", errSyntax},
    74  		{"'''\r'''", "", errMissingNewline},
    75  
    76  		{`#"Hello"#`, "Hello", nil},
    77  		{`#"Hello\v"#`, "Hello\\v", nil},
    78  		{`#"Hello\#v\r"#`, "Hello\v\\r", nil},
    79  		{`##"Hello\##v\r"##`, "Hello\v\\r", nil},
    80  		{`##"Hello\##v"##`, "Hello\v", nil},
    81  		{"#'''\n\t\tHello\\#v\n\t\t'''#", "Hello\v", nil},
    82  		{"##'''\n\t\tHello\\#v\n\t\t'''##", "Hello\\#v", nil},
    83  		{`#"""` + "\n\t\t\\#r\n\t\t" + `"""#`, "\r", nil},
    84  		{`#""#`, "", nil},
    85  		{`#" ""#`, ` "`, nil},
    86  		{`#" """#`, ` ""`, nil},
    87  		{`##" """# "##`, ` """# `, nil},
    88  		{`##" """# "##`, ` """# `, nil},
    89  		{`#"This is a "dog""#`, `This is a "dog"`, nil},
    90  		{"#\"\"\"\n\"\n\"\"\"#", `"`, nil},
    91  		{"#\"\"\"\n\"\"\"\n\"\"\"#", `"""`, nil},
    92  		{"#\"\"\"\n\na\n\n\"\"\"#", "\na\n", nil},
    93  		// Gobble extra \r
    94  		{"#\"\"\"\n\ra\n\r\"\"\"#", `a`, nil},
    95  		{"#\"\"\"\n\r\n\ra\n\r\n\r\"\"\"#", "\na\n", nil},
    96  		// Make sure this works for Windows.
    97  		{"#\"\"\"\r\n\r\na\r\n\r\n\"\"\"#", "\na\n", nil},
    98  		{"#\"\"\"\r\n \r\n a\r\n \r\n \"\"\"#", "\na\n", nil},
    99  		{"#\"\"\"\r\na\r\n\"\"\"#", `a`, nil},
   100  		{"#\"\"\"\r\n\ra\r\n\r\"\"\"#", `a`, nil},
   101  		{`####"   \"####`, `   \`, nil},
   102  
   103  		{"```", "", errSyntax},
   104  		{"Hello", "", errSyntax},
   105  		{`"Hello`, "", errUnmatchedQuote},
   106  		{`"""Hello"""`, "", errMissingNewline},
   107  		{"'''\n  Hello\n   '''", "", errInvalidWhitespace},
   108  		{"'''\n   a\n  b\n   '''", "", errInvalidWhitespace},
   109  		{`"Hello""`, "", errSyntax},
   110  		{`#"Hello"`, "", errUnmatchedQuote},
   111  		{`#"Hello'#`, "", errUnmatchedQuote},
   112  		{`#""" """#`, "", errMissingNewline},
   113  		{`"""` + "\r\n\tHello \\\r", "", errUnmatchedQuote},
   114  
   115  		// TODO: should this be legal?
   116  		{`#"""#`, "", errMissingNewline},
   117  	}
   118  	for i, tc := range testCases {
   119  		t.Run(fmt.Sprintf("%d/%s", i, tc.in), func(t *testing.T) {
   120  			if got, err := Unquote(tc.in); err != tc.err {
   121  				t.Errorf("error: got %#v; want %#v", err, tc.err)
   122  			} else if got != tc.out {
   123  				t.Errorf("value: got %q; want %q", got, tc.out)
   124  			}
   125  		})
   126  	}
   127  }
   128  
   129  func TestInterpolation(t *testing.T) {
   130  	testCases := []struct {
   131  		quotes string
   132  		in     string
   133  		out    string
   134  		err    error
   135  	}{
   136  		{`""`, `foo\(`, "foo", nil},
   137  		{`"""` + "\n" + `"""`, `foo`, "", errUnmatchedQuote},
   138  		{`#""#`, `foo\#(`, "foo", nil},
   139  		{`#""#`, `foo\(`, "", errUnmatchedQuote},
   140  		{`""`, `foo\(bar`, "", errSyntax},
   141  		{`""`, ``, "", errUnmatchedQuote},
   142  		{`#""#`, `"`, "", errUnmatchedQuote},
   143  		{`#""#`, `\`, "", errUnmatchedQuote},
   144  		{`##""##`, `\'`, "", errUnmatchedQuote},
   145  	}
   146  	for i, tc := range testCases {
   147  		t.Run(fmt.Sprintf("%d/%s/%s", i, tc.quotes, tc.in), func(t *testing.T) {
   148  			info, _, _, _ := ParseQuotes(tc.quotes, tc.quotes)
   149  			if got, err := info.Unquote(tc.in); err != tc.err {
   150  				t.Errorf("error: got %q; want %q", err, tc.err)
   151  			} else if got != tc.out {
   152  				t.Errorf("value: got %q; want %q", got, tc.out)
   153  			}
   154  		})
   155  	}
   156  }
   157  
   158  func TestIsDouble(t *testing.T) {
   159  	testCases := []struct {
   160  		quotes string
   161  		double bool
   162  	}{
   163  		{`""`, true},
   164  		{`"""` + "\n" + `"""`, true},
   165  		{`#""#`, true},
   166  		{`''`, false},
   167  		{`'''` + "\n" + `'''`, false},
   168  		{`#''#`, false},
   169  	}
   170  	for i, tc := range testCases {
   171  		t.Run(fmt.Sprintf("%d/%s", i, tc.quotes), func(t *testing.T) {
   172  			info, _, _, err := ParseQuotes(tc.quotes, tc.quotes)
   173  			if err != nil {
   174  				t.Fatal(err)
   175  			}
   176  			if got := info.IsDouble(); got != tc.double {
   177  				t.Errorf("got %v; want %v", got, tc.double)
   178  			}
   179  		})
   180  	}
   181  }
   182  

View as plain text