...

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

Documentation: cuelang.org/go/cue/literal

     1  // Copyright 2020 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  	"strings"
    20  	"testing"
    21  
    22  	"github.com/google/go-cmp/cmp"
    23  )
    24  
    25  func TestQuote(t *testing.T) {
    26  	testCases := []struct {
    27  		form  Form
    28  		in    string
    29  		out   string
    30  		lossy bool
    31  	}{
    32  		{form: String, in: "\x00", out: `"\u0000"`},
    33  		{form: String, in: "abc\xffdef", out: `"abc�def"`, lossy: true},
    34  		{form: Bytes, in: "abc\xffdef", out: `'abc\xffdef'`},
    35  		{form: String.WithASCIIOnly(),
    36  			in: "abc\xffdef", out: `"abc\ufffddef"`, lossy: true},
    37  		{form: String, in: "\a\b\f\r\n\t\v", out: `"\a\b\f\r\n\t\v"`},
    38  		{form: String, in: "\"", out: `"\""`},
    39  		{form: String, in: "\\", out: `"\\"`},
    40  		{form: String, in: "\u263a", out: `"☺"`},
    41  		{form: String, in: "\U0010ffff", out: `"\U0010ffff"`},
    42  		{form: String, in: "\x04", out: `"\u0004"`},
    43  		{form: Bytes, in: "\x04", out: `'\x04'`},
    44  		{form: String.WithASCIIOnly(), in: "\u263a", out: `"\u263a"`},
    45  		{form: String.WithGraphicOnly(), in: "\u263a", out: `"☺"`},
    46  		{
    47  			form: String.WithASCIIOnly(),
    48  			in:   "!\u00a0!\u2000!\u3000!",
    49  			out:  `"!\u00a0!\u2000!\u3000!"`,
    50  		},
    51  		{form: String, in: "a\nb", out: `"a\nb"`},
    52  		{form: String.WithTabIndent(3), in: "a\nb", out: `"""
    53  			a
    54  			b
    55  			"""`},
    56  		{form: String.WithTabIndent(3), in: "a", out: `"""
    57  			a
    58  			"""`},
    59  		{form: String.WithTabIndent(3), in: "a\n", out: `"""
    60  			a
    61  
    62  			"""`},
    63  		{form: String.WithTabIndent(3), in: "", out: `"""
    64  			"""`},
    65  		{form: String.WithTabIndent(3), in: "\n", out: `"""
    66  
    67  
    68  			"""`},
    69  		{form: String.WithTabIndent(3), in: "\n\n", out: `"""
    70  
    71  
    72  
    73  			"""`},
    74  		{form: String.WithOptionalTabIndent(3), in: "a", out: `"a"`},
    75  		{form: String.WithOptionalTabIndent(3), in: "a\n", out: `"""
    76  			a
    77  
    78  			"""`},
    79  
    80  		// Issue #541
    81  		{form: String.WithTabIndent(3), in: "foo\n\"bar\"", out: `"""
    82  			foo
    83  			"bar"
    84  			"""`},
    85  		{form: String.WithTabIndent(3), in: "foo\n\"\"\"bar\"", out: `#"""
    86  			foo
    87  			"""bar"
    88  			"""#`},
    89  		{form: String.WithTabIndent(3), in: "foo\n\"\"\"\"\"###bar\"", out: `####"""
    90  			foo
    91  			"""""###bar"
    92  			"""####`},
    93  		{form: String.WithTabIndent(3), in: "foo\n\"\"\"\r\f\\", out: `#"""
    94  			foo
    95  			"""\#r\#f\#\
    96  			"""#`},
    97  		{form: Bytes.WithTabIndent(3), in: "foo'''\nhello", out: `#'''
    98  			foo'''
    99  			hello
   100  			'''#`},
   101  		{form: Bytes.WithTabIndent(3), in: "foo\n'''\r\f\\", out: `#'''
   102  			foo
   103  			'''\#r\#f\#\
   104  			'''#`},
   105  	}
   106  	for _, tc := range testCases {
   107  		t.Run(fmt.Sprintf("%q", tc.in), func(t *testing.T) {
   108  			got := tc.form.Quote(tc.in)
   109  			if got != tc.out {
   110  				t.Errorf("Quote: %s", cmp.Diff(tc.out, got))
   111  			}
   112  
   113  			got = string(tc.form.Append(nil, tc.in))
   114  			if got != tc.out {
   115  				t.Errorf("Append: %s", cmp.Diff(tc.out, got))
   116  			}
   117  
   118  			str, err := Unquote(got)
   119  			if err != nil {
   120  				t.Errorf("Roundtrip error: %v", err)
   121  			}
   122  
   123  			if !tc.lossy && str != tc.in {
   124  				t.Errorf("Quote: %s", cmp.Diff(tc.in, str))
   125  			}
   126  		})
   127  	}
   128  }
   129  
   130  func TestAppendEscaped(t *testing.T) {
   131  	testCases := []struct {
   132  		form Form
   133  		in   string
   134  		out  string
   135  	}{
   136  		{String, "a", "a"},
   137  		{String, "", ""},
   138  		{String.WithTabIndent(2), "", ""},
   139  		{String.WithTabIndent(2), "\n", "\n"},
   140  		{String.WithTabIndent(2), "a\n", "a\n"},
   141  		{String.WithTabIndent(2), "a\nb", "a\n\t\tb"},
   142  	}
   143  	for _, tc := range testCases {
   144  		t.Run(tc.in, func(t *testing.T) {
   145  			buf := tc.form.AppendEscaped(nil, tc.in)
   146  			if got := string(buf); got != tc.out {
   147  				t.Error(cmp.Diff(tc.out, got))
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func BenchmarkQuote(b *testing.B) {
   154  	inputs := []string{
   155  		"aaaa",
   156  		"aaaaaaa\n\naaaaaa",
   157  		strings.Repeat("aaaaaaaaaaa\n", 1000),
   158  	}
   159  
   160  	for _, f := range []Form{
   161  		String,
   162  		Bytes,
   163  		String.WithTabIndent(3),
   164  		String.WithOptionalTabIndent(3),
   165  	} {
   166  		b.Run("", func(b *testing.B) {
   167  			for i := 0; i < b.N; i++ {
   168  				for _, s := range inputs {
   169  					f.Quote(s)
   170  				}
   171  			}
   172  		})
   173  	}
   174  }
   175  

View as plain text