xref: /aosp_15_r20/build/soong/jar/jar_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2017 Google Inc. All rights reserved.
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
15package jar
16
17import (
18	"bytes"
19	"io"
20	"testing"
21)
22
23func TestGetJavaPackage(t *testing.T) {
24	type args struct {
25		r   io.Reader
26		src string
27	}
28	tests := []struct {
29		name    string
30		in      string
31		want    string
32		wantErr bool
33	}{
34		{
35			name: "simple",
36			in:   "package foo.bar;",
37			want: "foo.bar",
38		},
39		{
40			name: "comment",
41			in:   "/* test */\npackage foo.bar;",
42			want: "foo.bar",
43		},
44		{
45			name: "no package",
46			in:   "import foo.bar;",
47			want: "",
48		},
49		{
50			name:    "missing semicolon error",
51			in:      "package foo.bar",
52			wantErr: true,
53		},
54		{
55			name:    "parser error",
56			in:      "/*",
57			wantErr: true,
58		},
59		{
60			name:    "parser ident error",
61			in:      "package 0foo.bar;",
62			wantErr: true,
63		},
64		{
65			name: "annotations",
66			in:   "@NonNullApi\n@X\npackage foo.bar;",
67			want: "foo.bar",
68		},
69		{
70			name:    "complex annotation",
71			in:      "@Foo(x=y)\n@package foo.bar;",
72			wantErr: true, // Complex annotation not supported yet.
73		},
74	}
75	for _, tt := range tests {
76		t.Run(tt.name, func(t *testing.T) {
77			buf := bytes.NewBufferString(tt.in)
78			got, err := JavaPackage(buf, "<test>")
79			if (err != nil) != tt.wantErr {
80				t.Errorf("JavaPackage() error = %v, wantErr %v", err, tt.wantErr)
81				return
82			}
83			if got != tt.want {
84				t.Errorf("JavaPackage() = %v, want %v", got, tt.want)
85			}
86		})
87	}
88}
89
90func Test_javaIdentRune(t *testing.T) {
91	// runes that should be valid anywhere in an identifier
92	validAnywhere := []rune{
93		// letters, $, _
94		'a',
95		'A',
96		'$',
97		'_',
98
99		// assorted unicode
100		'��',
101		'��',
102		'Dž',
103		'ῼ',
104		'ʰ',
105		'゚',
106		'ƻ',
107		'��',
108		'₩',
109		'_',
110		'Ⅰ',
111		'��',
112	}
113
114	// runes that should be invalid as the first rune in an identifier, but valid anywhere else
115	validAfterFirst := []rune{
116		// digits
117		'0',
118
119		// assorted unicode
120		'᥍',
121		'��',
122		'ྂ',
123		'��',
124
125		// control characters
126		'\x00',
127		'\b',
128		'\u000e',
129		'\u001b',
130		'\u007f',
131		'\u009f',
132		'\u00ad',
133		0xE007F,
134
135		// zero width space
136		'\u200b',
137	}
138
139	// runes that should never be valid in an identifier
140	invalid := []rune{
141		';',
142		0x110000,
143	}
144
145	validFirst := validAnywhere
146	invalidFirst := append(validAfterFirst, invalid...)
147	validPart := append(validAnywhere, validAfterFirst...)
148	invalidPart := invalid
149
150	check := func(t *testing.T, ch rune, i int, want bool) {
151		t.Helper()
152		if got := javaIdentRune(ch, i); got != want {
153			t.Errorf("javaIdentRune() = %v, want %v", got, want)
154		}
155	}
156
157	t.Run("first", func(t *testing.T) {
158		t.Run("valid", func(t *testing.T) {
159			for _, ch := range validFirst {
160				t.Run(string(ch), func(t *testing.T) {
161					check(t, ch, 0, true)
162				})
163			}
164		})
165
166		t.Run("invalid", func(t *testing.T) {
167			for _, ch := range invalidFirst {
168				t.Run(string(ch), func(t *testing.T) {
169					check(t, ch, 0, false)
170				})
171			}
172		})
173	})
174
175	t.Run("part", func(t *testing.T) {
176		t.Run("valid", func(t *testing.T) {
177			for _, ch := range validPart {
178				t.Run(string(ch), func(t *testing.T) {
179					check(t, ch, 1, true)
180				})
181			}
182		})
183
184		t.Run("invalid", func(t *testing.T) {
185			for _, ch := range invalidPart {
186				t.Run(string(ch), func(t *testing.T) {
187					check(t, ch, 1, false)
188				})
189			}
190		})
191	})
192}
193