1010import net .jqwik .api .Arbitraries ;
1111import net .jqwik .api .Arbitrary ;
1212import net .jqwik .api .Builders ;
13+ import net .jqwik .api .Combinators ;
1314import net .jqwik .api .ForAll ;
1415import net .jqwik .api .Property ;
1516import net .jqwik .api .Provide ;
3233import org .elasticsearch .index .mapper .FieldNamesFieldMapper ;
3334import org .elasticsearch .index .mapper .LuceneDocument ;
3435import org .elasticsearch .index .mapper .MappedFieldType ;
36+ import org .elasticsearch .index .mapper .Mapper ;
3537import org .elasticsearch .index .mapper .MapperService ;
3638import org .elasticsearch .index .mapper .SourceFieldMetrics ;
3739import org .elasticsearch .index .mapper .SourceLoader ;
@@ -64,7 +66,7 @@ static void beforeContainer() {
6466 @ Property (tries = 10000 )
6567 void blockLoaderReturnsCorrectResults (
6668 @ ForAll ("settings" ) Settings indexSettings ,
67- @ ForAll ("mapping " ) Map <String , Object > fieldMapping ,
69+ @ ForAll ("fieldMapping " ) Map <String , Object > fieldMapping ,
6870 @ ForAll ("document" ) Map <String , Object > document
6971 ) throws IOException {
7072 var mapping = Map .of ("_doc" , Map .of ("properties" , Map .of ("field" , fieldMapping )));
@@ -83,6 +85,15 @@ void blockLoaderReturnsCorrectResults(
8385 Assertions .assertEquals (expected , blockLoaderResult );
8486 }
8587
88+ @ Property
89+ void testComplexMapping (@ ForAll ("settings" ) Settings indexSettings , @ ForAll ("deepMapping" ) Map <String , Object > mapping ) throws IOException {
90+ var fullMapping = Map .of ("_doc" , Map .of ("properties" , Map .of ("top" , mapping )));
91+ var mappingXContent = XContentBuilder .builder (XContentType .JSON .xContent ()).map (fullMapping );
92+ var mapperService = createMapperService (indexSettings , mappingXContent );
93+
94+ mapperService .documentMapper ();
95+ }
96+
8697 @ Provide
8798 Arbitrary <Settings > settings () {
8899 var syntheticSource = Arbitraries .of (true , false );
@@ -98,7 +109,58 @@ Arbitrary<Settings> settings() {
98109 }
99110
100111 @ Provide
101- Arbitrary <Map <String , Object >> mapping () {
112+ Arbitrary <Map <String , Object >> deepMapping () {
113+ var depth = Arbitraries .integers ().between (0 , 5 );
114+
115+ return depth .flatMap (d -> objectLevel (d , objectMapping (), fieldMapping ()));
116+ }
117+
118+ @ Provide
119+ Arbitrary <Map <String , Object >> objectLevel (
120+ int remainingDepth ,
121+ Arbitrary <Map <String , Object >> objectMapping ,
122+ Arbitrary <Map <String , Object >> fieldMapping
123+ ) {
124+ if (remainingDepth == 0 ) {
125+ return Combinators .combine (objectMapping , fieldMapping ).as ((obj , f ) -> {
126+ var properties = new HashMap <>() {
127+ {
128+ put ("field" , f );
129+ }
130+ };
131+
132+ obj .put ("properties" , properties );
133+ return obj ;
134+ });
135+ }
136+
137+ var child = objectLevel (remainingDepth - 1 , objectMapping , fieldMapping );
138+ var childName = Arbitraries .strings ().ofLength (5 ).withCharRange ('a' , 'z' );
139+ return Combinators .combine (objectMapping , childName , child ).as ((parent , cn , c ) -> {
140+ var properties = new HashMap <>() {
141+ {
142+ put (cn , c );
143+ }
144+ };
145+
146+ parent .put ("properties" , properties );
147+ return parent ;
148+ });
149+ }
150+
151+ @ Provide
152+ Arbitrary <Map <String , Object >> objectMapping () {
153+ var syntheticSourceKeep = Arbitraries .of (Mapper .SourceKeepMode .values ());
154+
155+ return syntheticSourceKeep .map (ssk -> new HashMap <>() {
156+ {
157+ put ("synthetic_source_keep" , ssk .toString ());
158+ }
159+ });
160+ }
161+
162+ @ Provide
163+ Arbitrary <Map <String , Object >> fieldMapping () {
102164 var docValues = Arbitraries .of (true , false );
103165 var index = Arbitraries .of (true , false );
104166 var store = Arbitraries .of (true , false );
@@ -141,20 +203,6 @@ Arbitrary<Map<String, Object>> document() {
141203 return keywordValues .map (l -> Map .of ("field" , l ));
142204 }
143205
144- @ Provide
145- Arbitrary <Map <String , Object >> deepDocument () {
146- var keywordValues = Arbitraries .strings ()
147- .withCharRange ('0' , 'z' )
148- .ofMinLength (0 )
149- .ofMaxLength (50 )
150- .injectNull (0.05 )
151- .list ()
152- .ofMinSize (0 )
153- .ofMaxSize (10 );
154-
155- return keywordValues .map (l -> Map .of ("field" , l ));
156- }
157-
158206 private MapperService createMapperService (Settings indexSettings , XContentBuilder mappingXContent ) throws IOException {
159207 return new TestMapperServiceBuilder ().withSettings (indexSettings ).withMapping (mappingXContent ).build ();
160208 }
0 commit comments