cuelang.org/go@v0.10.1/cue/literal/string_test.go (about) 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 }