1*333d2b36SAndroid Build Coastguard Worker// Copyright 2017 Google Inc. All rights reserved. 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage jar 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "bytes" 19*333d2b36SAndroid Build Coastguard Worker "io" 20*333d2b36SAndroid Build Coastguard Worker "testing" 21*333d2b36SAndroid Build Coastguard Worker) 22*333d2b36SAndroid Build Coastguard Worker 23*333d2b36SAndroid Build Coastguard Workerfunc TestGetJavaPackage(t *testing.T) { 24*333d2b36SAndroid Build Coastguard Worker type args struct { 25*333d2b36SAndroid Build Coastguard Worker r io.Reader 26*333d2b36SAndroid Build Coastguard Worker src string 27*333d2b36SAndroid Build Coastguard Worker } 28*333d2b36SAndroid Build Coastguard Worker tests := []struct { 29*333d2b36SAndroid Build Coastguard Worker name string 30*333d2b36SAndroid Build Coastguard Worker in string 31*333d2b36SAndroid Build Coastguard Worker want string 32*333d2b36SAndroid Build Coastguard Worker wantErr bool 33*333d2b36SAndroid Build Coastguard Worker }{ 34*333d2b36SAndroid Build Coastguard Worker { 35*333d2b36SAndroid Build Coastguard Worker name: "simple", 36*333d2b36SAndroid Build Coastguard Worker in: "package foo.bar;", 37*333d2b36SAndroid Build Coastguard Worker want: "foo.bar", 38*333d2b36SAndroid Build Coastguard Worker }, 39*333d2b36SAndroid Build Coastguard Worker { 40*333d2b36SAndroid Build Coastguard Worker name: "comment", 41*333d2b36SAndroid Build Coastguard Worker in: "/* test */\npackage foo.bar;", 42*333d2b36SAndroid Build Coastguard Worker want: "foo.bar", 43*333d2b36SAndroid Build Coastguard Worker }, 44*333d2b36SAndroid Build Coastguard Worker { 45*333d2b36SAndroid Build Coastguard Worker name: "no package", 46*333d2b36SAndroid Build Coastguard Worker in: "import foo.bar;", 47*333d2b36SAndroid Build Coastguard Worker want: "", 48*333d2b36SAndroid Build Coastguard Worker }, 49*333d2b36SAndroid Build Coastguard Worker { 50*333d2b36SAndroid Build Coastguard Worker name: "missing semicolon error", 51*333d2b36SAndroid Build Coastguard Worker in: "package foo.bar", 52*333d2b36SAndroid Build Coastguard Worker wantErr: true, 53*333d2b36SAndroid Build Coastguard Worker }, 54*333d2b36SAndroid Build Coastguard Worker { 55*333d2b36SAndroid Build Coastguard Worker name: "parser error", 56*333d2b36SAndroid Build Coastguard Worker in: "/*", 57*333d2b36SAndroid Build Coastguard Worker wantErr: true, 58*333d2b36SAndroid Build Coastguard Worker }, 59*333d2b36SAndroid Build Coastguard Worker { 60*333d2b36SAndroid Build Coastguard Worker name: "parser ident error", 61*333d2b36SAndroid Build Coastguard Worker in: "package 0foo.bar;", 62*333d2b36SAndroid Build Coastguard Worker wantErr: true, 63*333d2b36SAndroid Build Coastguard Worker }, 64*333d2b36SAndroid Build Coastguard Worker { 65*333d2b36SAndroid Build Coastguard Worker name: "annotations", 66*333d2b36SAndroid Build Coastguard Worker in: "@NonNullApi\n@X\npackage foo.bar;", 67*333d2b36SAndroid Build Coastguard Worker want: "foo.bar", 68*333d2b36SAndroid Build Coastguard Worker }, 69*333d2b36SAndroid Build Coastguard Worker { 70*333d2b36SAndroid Build Coastguard Worker name: "complex annotation", 71*333d2b36SAndroid Build Coastguard Worker in: "@Foo(x=y)\n@package foo.bar;", 72*333d2b36SAndroid Build Coastguard Worker wantErr: true, // Complex annotation not supported yet. 73*333d2b36SAndroid Build Coastguard Worker }, 74*333d2b36SAndroid Build Coastguard Worker } 75*333d2b36SAndroid Build Coastguard Worker for _, tt := range tests { 76*333d2b36SAndroid Build Coastguard Worker t.Run(tt.name, func(t *testing.T) { 77*333d2b36SAndroid Build Coastguard Worker buf := bytes.NewBufferString(tt.in) 78*333d2b36SAndroid Build Coastguard Worker got, err := JavaPackage(buf, "<test>") 79*333d2b36SAndroid Build Coastguard Worker if (err != nil) != tt.wantErr { 80*333d2b36SAndroid Build Coastguard Worker t.Errorf("JavaPackage() error = %v, wantErr %v", err, tt.wantErr) 81*333d2b36SAndroid Build Coastguard Worker return 82*333d2b36SAndroid Build Coastguard Worker } 83*333d2b36SAndroid Build Coastguard Worker if got != tt.want { 84*333d2b36SAndroid Build Coastguard Worker t.Errorf("JavaPackage() = %v, want %v", got, tt.want) 85*333d2b36SAndroid Build Coastguard Worker } 86*333d2b36SAndroid Build Coastguard Worker }) 87*333d2b36SAndroid Build Coastguard Worker } 88*333d2b36SAndroid Build Coastguard Worker} 89*333d2b36SAndroid Build Coastguard Worker 90*333d2b36SAndroid Build Coastguard Workerfunc Test_javaIdentRune(t *testing.T) { 91*333d2b36SAndroid Build Coastguard Worker // runes that should be valid anywhere in an identifier 92*333d2b36SAndroid Build Coastguard Worker validAnywhere := []rune{ 93*333d2b36SAndroid Build Coastguard Worker // letters, $, _ 94*333d2b36SAndroid Build Coastguard Worker 'a', 95*333d2b36SAndroid Build Coastguard Worker 'A', 96*333d2b36SAndroid Build Coastguard Worker '$', 97*333d2b36SAndroid Build Coastguard Worker '_', 98*333d2b36SAndroid Build Coastguard Worker 99*333d2b36SAndroid Build Coastguard Worker // assorted unicode 100*333d2b36SAndroid Build Coastguard Worker '', 101*333d2b36SAndroid Build Coastguard Worker '', 102*333d2b36SAndroid Build Coastguard Worker 'Dž', 103*333d2b36SAndroid Build Coastguard Worker 'ῼ', 104*333d2b36SAndroid Build Coastguard Worker 'ʰ', 105*333d2b36SAndroid Build Coastguard Worker '゚', 106*333d2b36SAndroid Build Coastguard Worker 'ƻ', 107*333d2b36SAndroid Build Coastguard Worker '', 108*333d2b36SAndroid Build Coastguard Worker '₩', 109*333d2b36SAndroid Build Coastguard Worker '_', 110*333d2b36SAndroid Build Coastguard Worker 'Ⅰ', 111*333d2b36SAndroid Build Coastguard Worker '', 112*333d2b36SAndroid Build Coastguard Worker } 113*333d2b36SAndroid Build Coastguard Worker 114*333d2b36SAndroid Build Coastguard Worker // runes that should be invalid as the first rune in an identifier, but valid anywhere else 115*333d2b36SAndroid Build Coastguard Worker validAfterFirst := []rune{ 116*333d2b36SAndroid Build Coastguard Worker // digits 117*333d2b36SAndroid Build Coastguard Worker '0', 118*333d2b36SAndroid Build Coastguard Worker 119*333d2b36SAndroid Build Coastguard Worker // assorted unicode 120*333d2b36SAndroid Build Coastguard Worker '᥍', 121*333d2b36SAndroid Build Coastguard Worker '', 122*333d2b36SAndroid Build Coastguard Worker 'ྂ', 123*333d2b36SAndroid Build Coastguard Worker '', 124*333d2b36SAndroid Build Coastguard Worker 125*333d2b36SAndroid Build Coastguard Worker // control characters 126*333d2b36SAndroid Build Coastguard Worker '\x00', 127*333d2b36SAndroid Build Coastguard Worker '\b', 128*333d2b36SAndroid Build Coastguard Worker '\u000e', 129*333d2b36SAndroid Build Coastguard Worker '\u001b', 130*333d2b36SAndroid Build Coastguard Worker '\u007f', 131*333d2b36SAndroid Build Coastguard Worker '\u009f', 132*333d2b36SAndroid Build Coastguard Worker '\u00ad', 133*333d2b36SAndroid Build Coastguard Worker 0xE007F, 134*333d2b36SAndroid Build Coastguard Worker 135*333d2b36SAndroid Build Coastguard Worker // zero width space 136*333d2b36SAndroid Build Coastguard Worker '\u200b', 137*333d2b36SAndroid Build Coastguard Worker } 138*333d2b36SAndroid Build Coastguard Worker 139*333d2b36SAndroid Build Coastguard Worker // runes that should never be valid in an identifier 140*333d2b36SAndroid Build Coastguard Worker invalid := []rune{ 141*333d2b36SAndroid Build Coastguard Worker ';', 142*333d2b36SAndroid Build Coastguard Worker 0x110000, 143*333d2b36SAndroid Build Coastguard Worker } 144*333d2b36SAndroid Build Coastguard Worker 145*333d2b36SAndroid Build Coastguard Worker validFirst := validAnywhere 146*333d2b36SAndroid Build Coastguard Worker invalidFirst := append(validAfterFirst, invalid...) 147*333d2b36SAndroid Build Coastguard Worker validPart := append(validAnywhere, validAfterFirst...) 148*333d2b36SAndroid Build Coastguard Worker invalidPart := invalid 149*333d2b36SAndroid Build Coastguard Worker 150*333d2b36SAndroid Build Coastguard Worker check := func(t *testing.T, ch rune, i int, want bool) { 151*333d2b36SAndroid Build Coastguard Worker t.Helper() 152*333d2b36SAndroid Build Coastguard Worker if got := javaIdentRune(ch, i); got != want { 153*333d2b36SAndroid Build Coastguard Worker t.Errorf("javaIdentRune() = %v, want %v", got, want) 154*333d2b36SAndroid Build Coastguard Worker } 155*333d2b36SAndroid Build Coastguard Worker } 156*333d2b36SAndroid Build Coastguard Worker 157*333d2b36SAndroid Build Coastguard Worker t.Run("first", func(t *testing.T) { 158*333d2b36SAndroid Build Coastguard Worker t.Run("valid", func(t *testing.T) { 159*333d2b36SAndroid Build Coastguard Worker for _, ch := range validFirst { 160*333d2b36SAndroid Build Coastguard Worker t.Run(string(ch), func(t *testing.T) { 161*333d2b36SAndroid Build Coastguard Worker check(t, ch, 0, true) 162*333d2b36SAndroid Build Coastguard Worker }) 163*333d2b36SAndroid Build Coastguard Worker } 164*333d2b36SAndroid Build Coastguard Worker }) 165*333d2b36SAndroid Build Coastguard Worker 166*333d2b36SAndroid Build Coastguard Worker t.Run("invalid", func(t *testing.T) { 167*333d2b36SAndroid Build Coastguard Worker for _, ch := range invalidFirst { 168*333d2b36SAndroid Build Coastguard Worker t.Run(string(ch), func(t *testing.T) { 169*333d2b36SAndroid Build Coastguard Worker check(t, ch, 0, false) 170*333d2b36SAndroid Build Coastguard Worker }) 171*333d2b36SAndroid Build Coastguard Worker } 172*333d2b36SAndroid Build Coastguard Worker }) 173*333d2b36SAndroid Build Coastguard Worker }) 174*333d2b36SAndroid Build Coastguard Worker 175*333d2b36SAndroid Build Coastguard Worker t.Run("part", func(t *testing.T) { 176*333d2b36SAndroid Build Coastguard Worker t.Run("valid", func(t *testing.T) { 177*333d2b36SAndroid Build Coastguard Worker for _, ch := range validPart { 178*333d2b36SAndroid Build Coastguard Worker t.Run(string(ch), func(t *testing.T) { 179*333d2b36SAndroid Build Coastguard Worker check(t, ch, 1, true) 180*333d2b36SAndroid Build Coastguard Worker }) 181*333d2b36SAndroid Build Coastguard Worker } 182*333d2b36SAndroid Build Coastguard Worker }) 183*333d2b36SAndroid Build Coastguard Worker 184*333d2b36SAndroid Build Coastguard Worker t.Run("invalid", func(t *testing.T) { 185*333d2b36SAndroid Build Coastguard Worker for _, ch := range invalidPart { 186*333d2b36SAndroid Build Coastguard Worker t.Run(string(ch), func(t *testing.T) { 187*333d2b36SAndroid Build Coastguard Worker check(t, ch, 1, false) 188*333d2b36SAndroid Build Coastguard Worker }) 189*333d2b36SAndroid Build Coastguard Worker } 190*333d2b36SAndroid Build Coastguard Worker }) 191*333d2b36SAndroid Build Coastguard Worker }) 192*333d2b36SAndroid Build Coastguard Worker} 193