1414
1515package com .google .api .generator .util ;
1616
17+ import static junit .framework .Assert .assertEquals ;
1718import static junit .framework .Assert .assertFalse ;
1819import static junit .framework .Assert .assertTrue ;
1920
21+ import com .google .api .generator .testutils .LineFormatter ;
2022import java .util .Arrays ;
2123import java .util .List ;
24+ import java .util .function .BiFunction ;
2225import java .util .function .Function ;
2326import org .junit .Test ;
2427
2528public class TrieTest {
2629 @ Test
27- public void stringTrie () {
30+ public void insertAndSearch_stringTrie () {
2831 Trie <String > trie = new Trie <>();
2932
3033 Function <String , List <String >> wordToCharListFn = w -> Arrays .asList (w .split ("(?!^)" ));
@@ -43,7 +46,7 @@ public void stringTrie() {
4346 }
4447
4548 @ Test
46- public void multiStringTrie () {
49+ public void insertAndSearch_multiStringTrie () {
4750 Trie <String > trie = new Trie <>();
4851 assertFalse (trie .search (Arrays .asList ("user" , "identity" , "name" )));
4952
@@ -62,4 +65,191 @@ public void multiStringTrie() {
6265 assertFalse (trie .hasPrefix (Arrays .asList ("identity" )));
6366 assertFalse (trie .hasPrefix (Arrays .asList ("contact" )));
6467 }
68+
69+ @ Test
70+ public void dfsTraverseAndReduce_emptyTrie () {
71+ // Add up points in the tree, where each parent gets (num child node points) * 2 + 1.
72+ int baseValue = 0 ;
73+ Function <String , Integer > parentPreprocFn = nodeVal -> new Integer (0 );
74+ BiFunction <String , Integer , Integer > leafReduceFn =
75+ (nodeVal , accVal ) -> new Integer (accVal + 1 );
76+ TriFunction <String , Integer , Integer , Integer > parentPostprocFn =
77+ (nodeVal , baseVal , accVal ) -> new Integer (nodeVal == null ? 0 : accVal * 2 + 1 );
78+
79+ Trie <String > trie = new Trie <>();
80+ int finalValue = trie .dfsTraverseAndReduce (parentPreprocFn , parentPostprocFn , leafReduceFn , 0 );
81+ assertEquals (0 , finalValue );
82+ }
83+
84+ @ Test
85+ public void dfsTraverseAndReduce_singleNodeTrie () {
86+ // Add up points in the tree, where each parent gets (num child node points) * 2 + 1.
87+ int baseValue = 0 ;
88+ Function <String , Integer > parentPreprocFn = nodeVal -> new Integer (0 );
89+ BiFunction <String , Integer , Integer > leafReduceFn =
90+ (nodeVal , accVal ) -> new Integer (accVal + 1 );
91+ TriFunction <String , Integer , Integer , Integer > parentPostprocFn =
92+ (nodeVal , baseVal , accVal ) -> new Integer (nodeVal == null ? accVal : accVal * 2 + 1 );
93+
94+ Trie <String > trie = new Trie <>();
95+ trie .insert (Arrays .asList ("user" ));
96+ int finalValue = trie .dfsTraverseAndReduce (parentPreprocFn , parentPostprocFn , leafReduceFn , 0 );
97+ assertEquals (1 , finalValue );
98+ }
99+
100+ @ Test
101+ public void dfsTraverseAndReduce_oneParentOneChildBranchTrie () {
102+ Function <String , String > toUpperCaseFn = s -> s .substring (0 , 1 ).toUpperCase () + s .substring (1 );
103+ Function <String , StringBuilder > parentPreprocFn =
104+ nodeVal ->
105+ new StringBuilder (String .format ("%s.newBuilder()" , toUpperCaseFn .apply (nodeVal )));
106+ BiFunction <String , StringBuilder , StringBuilder > leafReduceFn =
107+ (nodeVal , parentAccVal ) -> {
108+ parentAccVal .append (
109+ String .format (
110+ ".set%s(\" %s\" )" , toUpperCaseFn .apply (nodeVal .toString ()), nodeVal .toString ()));
111+ return parentAccVal ;
112+ };
113+ TriFunction <String , StringBuilder , StringBuilder , StringBuilder > parentPostprocFn =
114+ (nodeVal , baseVal , accVal ) -> {
115+ boolean isRootNode = nodeVal == null ;
116+ if (!isRootNode ) {
117+ baseVal .append (
118+ String .format (
119+ ".set%s(%s.build())" ,
120+ toUpperCaseFn .apply (nodeVal .toString ()), accVal .toString ()));
121+ }
122+ return isRootNode ? accVal : baseVal ;
123+ };
124+ StringBuilder baseVal = new StringBuilder ("RequestType.newBuilder()" );
125+
126+ Trie <String > trie = new Trie <>();
127+ trie .insert (Arrays .asList ("user" , "identity" ));
128+ String finalValue =
129+ trie .dfsTraverseAndReduce (parentPreprocFn , parentPostprocFn , leafReduceFn , baseVal )
130+ .toString ();
131+
132+ assertEquals (
133+ LineFormatter .lines (
134+ "RequestType.newBuilder()" ,
135+ ".setUser(User.newBuilder()" ,
136+ ".setIdentity(\" identity\" ).build())" ,
137+ ".build();" ),
138+ finalValue + ".build();" );
139+ }
140+
141+ @ Test
142+ public void dfsTraverseAndReduce_oneDeepBranchTrie () {
143+ // Add up points in the tree, where each parent gets (num child node points) * 2 + 1.
144+ int simpleBaseValue = 0 ;
145+ Function <String , Integer > simpleParentPreprocFn = nodeVal -> new Integer (0 );
146+ BiFunction <String , Integer , Integer > simpleLeafReduceFn =
147+ (nodeVal , accVal ) -> new Integer (accVal + 1 );
148+ TriFunction <String , Integer , Integer , Integer > simpleParentPostprocFn =
149+ (nodeVal , baseVal , accVal ) -> new Integer (nodeVal == null ? accVal : accVal * 2 + 1 );
150+
151+ Trie <String > trie = new Trie <>();
152+ trie .insert (Arrays .asList ("user" , "identity" , "name" , "firstName" ));
153+ int simpleFinalValue =
154+ trie .dfsTraverseAndReduce (
155+ simpleParentPreprocFn , simpleParentPostprocFn , simpleLeafReduceFn , simpleBaseValue );
156+ assertEquals (15 , simpleFinalValue );
157+
158+ Function <String , String > toUpperCaseFn = s -> s .substring (0 , 1 ).toUpperCase () + s .substring (1 );
159+ Function <String , StringBuilder > parentPreprocFn =
160+ nodeVal ->
161+ new StringBuilder (String .format ("%s.newBuilder()" , toUpperCaseFn .apply (nodeVal )));
162+ BiFunction <String , StringBuilder , StringBuilder > leafReduceFn =
163+ (nodeVal , parentAccVal ) -> {
164+ parentAccVal .append (
165+ String .format (
166+ ".set%s(\" %s\" )" , toUpperCaseFn .apply (nodeVal .toString ()), nodeVal .toString ()));
167+ return parentAccVal ;
168+ };
169+ TriFunction <String , StringBuilder , StringBuilder , StringBuilder > parentPostprocFn =
170+ (nodeVal , baseVal , accVal ) -> {
171+ boolean isRootNode = nodeVal == null ;
172+ if (!isRootNode ) {
173+ baseVal .append (
174+ String .format (
175+ ".set%s(%s.build())" ,
176+ toUpperCaseFn .apply (nodeVal .toString ()), accVal .toString ()));
177+ }
178+ return isRootNode ? accVal : baseVal ;
179+ };
180+ StringBuilder baseVal = new StringBuilder ("RequestType.newBuilder()" );
181+
182+ String finalValue =
183+ trie .dfsTraverseAndReduce (parentPreprocFn , parentPostprocFn , leafReduceFn , baseVal )
184+ .toString ();
185+
186+ assertEquals (
187+ LineFormatter .lines (
188+ "RequestType.newBuilder()" ,
189+ ".setUser(User.newBuilder()" ,
190+ ".setIdentity(Identity.newBuilder()" ,
191+ ".setName(Name.newBuilder()" ,
192+ ".setFirstName(\" firstName\" ).build())" ,
193+ ".build())" ,
194+ ".build())" ,
195+ ".build();" ),
196+ finalValue + ".build();" );
197+ }
198+
199+ @ Test
200+ public void dfsTraverseAndReduce_depthAndBreathTrie () {
201+ Function <String , String > toUpperCaseFn = s -> s .substring (0 , 1 ).toUpperCase () + s .substring (1 );
202+ Function <String , StringBuilder > parentPreprocFn =
203+ nodeVal ->
204+ new StringBuilder (String .format ("%s.newBuilder()" , toUpperCaseFn .apply (nodeVal )));
205+ BiFunction <String , StringBuilder , StringBuilder > leafReduceFn =
206+ (nodeVal , parentAccVal ) -> {
207+ parentAccVal .append (
208+ String .format (
209+ ".set%s(\" %s\" )" , toUpperCaseFn .apply (nodeVal .toString ()), nodeVal .toString ()));
210+ return parentAccVal ;
211+ };
212+ TriFunction <String , StringBuilder , StringBuilder , StringBuilder > parentPostprocFn =
213+ (nodeVal , baseVal , accVal ) -> {
214+ boolean isRootNode = nodeVal == null ;
215+ if (!isRootNode ) {
216+ baseVal .append (
217+ String .format (
218+ ".set%s(%s.build())" ,
219+ toUpperCaseFn .apply (nodeVal .toString ()), accVal .toString ()));
220+ }
221+ return isRootNode ? accVal : baseVal ;
222+ };
223+ StringBuilder baseVal = new StringBuilder ("RequestType.newBuilder()" );
224+
225+ Trie <String > trie = new Trie <>();
226+ trie .insert (Arrays .asList ("user" , "identity" , "name" , "firstName" ));
227+ trie .insert (Arrays .asList ("user" , "identity" , "name" , "lastName" ));
228+ trie .insert (Arrays .asList ("user" , "email" ));
229+ trie .insert (Arrays .asList ("user" , "age" ));
230+ trie .insert (Arrays .asList ("user" , "hobby" , "hobbyName" ));
231+ trie .insert (Arrays .asList ("user" , "hobby" , "frequency" ));
232+
233+ String finalValue =
234+ trie .dfsTraverseAndReduce (parentPreprocFn , parentPostprocFn , leafReduceFn , baseVal )
235+ .toString ();
236+
237+ assertEquals (
238+ LineFormatter .lines (
239+ "RequestType.newBuilder()" ,
240+ ".setUser(User.newBuilder()" ,
241+ ".setIdentity(Identity.newBuilder()" ,
242+ ".setName(Name.newBuilder()" ,
243+ ".setFirstName(\" firstName\" )" ,
244+ ".setLastName(\" lastName\" ).build())" , // Name.newBuilder().build().
245+ ".build())" , // Identity.newBuilder().build().
246+ ".setEmail(\" email\" )" ,
247+ ".setAge(\" age\" )" ,
248+ ".setHobby(Hobby.newBuilder()" ,
249+ ".setHobbyName(\" hobbyName\" )" ,
250+ ".setFrequency(\" frequency\" ).build())" , // Hobby.newBuilder().build().
251+ ".build())" , // User.newBuilder().build().
252+ ".build();" ),
253+ finalValue + ".build();" );
254+ }
65255}
0 commit comments