• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Bazel Authors. 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 liteparse
16
17import (
18	"bytes"
19	"context"
20	"reflect"
21	"strings"
22	"testing"
23
24	"src/tools/ak/res/res"
25	"src/tools/ak/res/respipe/respipe"
26	"src/tools/ak/res/resxml/resxml"
27)
28
29func TestResValuesParse(t *testing.T) {
30	tests := []struct {
31		doc       string
32		wanted    []string
33		wantedErr []string
34	}{
35		{
36			doc: `<resources>
37			<integer name='two'>2</integer>
38			<string name='embedded_stuff'>hi <b>there</b></string>
39			</resources>`,
40			wanted: []string{
41				"res-auto:integer/two",
42				"res-auto:string/embedded_stuff",
43			},
44		},
45		{
46			doc: `<resources>
47			<fraction name='frac'>12dp</fraction>
48			<item type='id' name='foo'/>
49      <id name='two'/>
50			<bool name='on'>true</bool>
51			</resources>`,
52			wanted: []string{
53				"res-auto:fraction/frac",
54				"res-auto:id/foo",
55				"res-auto:id/two",
56				"res-auto:bool/on",
57			},
58		},
59		{
60			doc: `<resources>
61			<color name='red'>#fff</color>
62			<item name='hundred' type='dimen'>100%</item>
63			<attr name="custom">
64				<enum name="cars" value="21"/>
65				<enum name="planes" value="42"/>
66			</attr>
67			<eat-comment/>
68			<!-- a comment -->
69			<attr name='textSize'/>
70			</resources>`,
71			wanted: []string{
72				"res-auto:color/red",
73				"res-auto:dimen/hundred",
74				"res-auto:id/cars",
75				"res-auto:id/planes",
76				"res-auto:attr/custom",
77				"res-auto:attr/textSize",
78			},
79		},
80		{
81			doc: `<resources>
82			<attr name='touch'>
83				<flag name="tap" value="0"/>
84				<flag name="double_tap" value="2"/>
85			</attr>
86			<integer-array name='empty'>
87			</integer-array>
88			<integer-array name='five'>
89				<item>1</item>
90				<item>@integer/two</item>
91			</integer-array>
92			</resources>`,
93
94			wanted: []string{
95				"res-auto:id/tap",
96				"res-auto:id/double_tap",
97				"res-auto:attr/touch",
98				"res-auto:array/empty",
99				"res-auto:array/five",
100			},
101		},
102		{
103
104			doc: `<resources>
105					<declare-styleable name='absPieChart'>
106						<attr name='android:gravity'/>
107						<attr name='local' format='string'/>
108						<attr name='overlay'>
109							<flag name="transparent" value="0"/>
110							<flag name="awesome" value="2"/>
111						</attr>
112					</declare-styleable>
113		  	</resources>`,
114			wanted: []string{
115				"res-auto:attr/local",
116				"res-auto:id/transparent",
117				"res-auto:id/awesome",
118				"res-auto:attr/overlay",
119				"res-auto:styleable/absPieChart",
120			},
121		},
122		{
123			doc:       `<resources><string>2</string></resources>`,
124			wantedErr: []string{"Expected to encounter name attribute"},
125		},
126	}
127
128	for _, tc := range tests {
129		ctx, cancel := context.WithCancel(context.Background())
130		defer cancel()
131		xmlC, xmlErrC := resxml.StreamDoc(ctx, bytes.NewBufferString(tc.doc))
132		resC, parseErrC := valuesParse(ctx, xmlC)
133		errC := respipe.MergeErrStreams(ctx, []<-chan error{xmlErrC, parseErrC})
134		var parsedNames []string
135		var errStrs []string
136		for resC != nil || errC != nil {
137			select {
138			case r, ok := <-resC:
139				if !ok {
140					resC = nil
141					continue
142				}
143				pn, err := res.ParseName(r.GetName(), res.Type(r.ResourceType))
144				if err != nil {
145					t.Errorf("res.ParseName(%s, %v) unexpected err: %v", r.GetName(), r.ResourceType, err)
146				}
147				parsedNames = append(parsedNames, pn.String())
148			case e, ok := <-errC:
149				if !ok {
150					errC = nil
151					continue
152				}
153				errStrs = append(errStrs, e.Error())
154			}
155
156		}
157
158		if !reflect.DeepEqual(parsedNames, tc.wanted) {
159			t.Errorf("valuesParse of: %s got: %s wanted: %s", tc.doc, parsedNames, tc.wanted)
160		}
161		if len(errStrs) != len(tc.wantedErr) {
162			t.Errorf("%s: unexpected amount of errs: %v wanted: %v", tc.doc, errStrs, tc.wantedErr)
163			continue
164		}
165		for i, e := range errStrs {
166			if !strings.Contains(e, tc.wantedErr[i]) {
167				t.Errorf("doc: %q got err: %s should contain: %s", tc.doc, e, tc.wantedErr[i])
168			}
169		}
170	}
171}
172