Source file src/cmd/internal/objabi/flag_test.go

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package objabi
     6  
     7  import (
     8  	"slices"
     9  	"testing"
    10  )
    11  
    12  func TestParseArgs(t *testing.T) {
    13  	t.Parallel()
    14  	tests := []struct {
    15  		name  string
    16  		input string
    17  		want  []string
    18  	}{
    19  		// GCC-compatibility test cases from test-expandargv.c
    20  		// Source code: https://github.com/gcc-mirror/gcc/blob/releases/gcc-15.2.0/libiberty/testsuite/test-expandargv.c#L72
    21  		{`crlf`, "a\r\nb", []string{"a", "b"}},                                       // test 0
    22  		{"newline", "a\nb", []string{"a", "b"}},                                      // test 1
    23  		{"null byte in arg", "a\x00b", []string{"a\x00b"}},                           // test 2: GCC parser gives ["a"]
    24  		{"null byte only", "\x00", []string{"\x00"}},                                 // test 3: GCC parser gives []
    25  		{"leading newline", "\na\nb", []string{"a", "b"}},                            // test 4
    26  		{"empty quotes", "a\n''\nb", []string{"a", "", "b"}},                         // test 5
    27  		{"quoted newlines", "a\n'a\n\nb'\nb", []string{"a", "a\n\nb", "b"}},          // test 6
    28  		{"single quote no escapes", "'a\\$VAR' '\\\"'", []string{"a\\$VAR", "\\\""}}, // test 7
    29  		{"line continuation", "\"ab\\\ncd\" ef\\\ngh", []string{"abcd", "efgh"}},     // test 8
    30  		// test 8.1 (additional verification for Windows line separators)
    31  		{"line continuation crlf", "\"ab\\\r\ncd\" ef\\\r\ngh", []string{"abcd", "efgh"}},
    32  		{"double quote escapes", "\"\\$VAR\" \"\\`\" \"\\\"\" \"\\\\\" \"\\n\" \"\\t\"",
    33  			[]string{"$VAR", "`", `"`, `\`, `\n`, `\t`}}, // test 9
    34  		{"whitespace only", "\t \n \t ", nil}, // test 10
    35  		{"single space", " ", nil},            // test 11
    36  		{"multiple spaces", "   ", nil},       // test 12
    37  
    38  		// Additional edge cases for peace of mind
    39  		{"basic split", "a b c", []string{"a", "b", "c"}},
    40  		{"tabs", "a\tb\tc", []string{"a", "b", "c"}},
    41  		{"mixed quotes", `a 'b c' "d e"`, []string{"a", "b c", "d e"}},
    42  		{"adjacent quotes", `'a'"b"`, []string{"ab"}}, // no whitespace - no split
    43  		{"empty input", "", nil},
    44  		{"empty single quotes", "''", []string{""}},
    45  		{"empty double quotes", `""`, []string{""}},
    46  		{"nested quotes in single", `'"hello"'`, []string{`"hello"`}},
    47  		{"nested quotes in double", `"'hello'"`, []string{"'hello'"}},
    48  		// GCC-specific (differs from LLVM): backslash outside quotes escapes the next character
    49  		{"backslash escape outside quotes", `\abc`, []string{"abc"}},
    50  		{"trailing backslash", `abc\`, []string{"abc"}},
    51  	}
    52  	for _, tt := range tests {
    53  		t.Run(tt.name, func(t *testing.T) {
    54  			got := ParseArgs([]byte(tt.input))
    55  			if !slices.Equal(got, tt.want) {
    56  				t.Errorf("parseArgs(%q) = %q, want %q", tt.input, got, tt.want)
    57  			}
    58  		})
    59  	}
    60  }
    61  

View as plain text