blob: 61da9bb6f6328d69a51d494aea9882581f6f846b [file] [log] [blame]
Colin Cross9cb51db2019-06-17 14:12:41 -07001// 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 },
Anton Hansson2863e452023-09-22 07:17:37 +000064 {
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 },
Colin Cross9cb51db2019-06-17 14:12:41 -070074 }
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) {
Colin Cross9cb51db2019-06-17 14:12:41 -070091 // 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}