@@ -189,6 +189,90 @@ private void doWithRandomAccessPattern(Consumer<IngestDocument> action) throws E
189189 doWithAccessPattern (randomFrom (IngestPipelineFieldAccessPattern .values ()), action );
190190 }
191191
192+ private void assertPathValid (IngestDocument doc , String path ) {
193+ // The fields being checked do not exist, so they all return false when running hasField
194+ assertFalse (doc .hasField (path ));
195+ }
196+
197+ private void assertPathInvalid (IngestDocument doc , String path , String errorMessage ) {
198+ IllegalArgumentException expected = expectThrows (IllegalArgumentException .class , () -> doc .hasField (path ));
199+ assertThat (expected .getMessage (), equalTo (errorMessage ));
200+ }
201+
202+ public void testPathParsingLogic () throws Exception {
203+ // Force a blank document for this test
204+ document = new IngestDocument ("index" , "id" , 1 , null , null , new HashMap <>());
205+
206+ doWithRandomAccessPattern ((doc ) -> {
207+ assertPathInvalid (doc , null , "path cannot be null nor empty" );
208+ assertPathInvalid (doc , "" , "path cannot be null nor empty" );
209+ assertPathValid (doc , "a" );
210+ assertPathValid (doc , "ab" );
211+ assertPathValid (doc , "abc" );
212+ assertPathValid (doc , "a.b" );
213+ assertPathValid (doc , "a.b.c" );
214+ // Trailing empty strings are trimmed by field path parsing logic
215+ assertPathValid (doc , "a." );
216+ assertPathValid (doc , "a.." );
217+ assertPathValid (doc , "a..." );
218+ // Empty field names are not allowed in the beginning or middle of the path though
219+ assertPathInvalid (doc , ".a.b" , "fieldName cannot be empty" );
220+ assertPathInvalid (doc , "a..b" , "fieldName cannot be empty" );
221+ });
222+
223+ doWithAccessPattern (CLASSIC , (doc ) -> {
224+ // Classic allows number fields because they are treated as either field names or array indices depending on context
225+ assertPathValid (doc , "a.0" );
226+ // Classic allows square brackets because it is not part of it's syntax
227+ assertPathValid (doc , "a[0]" );
228+ assertPathValid (doc , "a[]" );
229+ assertPathValid (doc , "a][" );
230+ assertPathValid (doc , "[" );
231+ assertPathValid (doc , "a[" );
232+ assertPathValid (doc , "[a" );
233+ assertPathValid (doc , "]" );
234+ assertPathValid (doc , "a]" );
235+ assertPathValid (doc , "]a" );
236+ assertPathValid (doc , "[]" );
237+ assertPathValid (doc , "][" );
238+ assertPathValid (doc , "[a]" );
239+ assertPathValid (doc , "]a[" );
240+ assertPathValid (doc , "[]a" );
241+ assertPathValid (doc , "][a" );
242+ });
243+
244+ doWithAccessPattern (FLEXIBLE , (doc ) -> {
245+ // Flexible has specific handling of square brackets
246+ assertPathInvalid (doc , "a[0]" , "path [a[0]] is not valid" );
247+ assertPathInvalid (doc , "a[]" , "path [a[]] is not valid" );
248+ assertPathInvalid (doc , "a][" , "path [a][] is not valid" );
249+ assertPathInvalid (doc , "[" , "path [[] is not valid" );
250+ assertPathInvalid (doc , "a[" , "path [a[] is not valid" );
251+ assertPathInvalid (doc , "[a" , "path [[a] is not valid" );
252+ assertPathInvalid (doc , "]" , "path []] is not valid" );
253+ assertPathInvalid (doc , "a]" , "path [a]] is not valid" );
254+ assertPathInvalid (doc , "]a" , "path []a] is not valid" );
255+ assertPathInvalid (doc , "[]" , "path [[]] is not valid" );
256+ assertPathInvalid (doc , "][" , "path [][] is not valid" );
257+ assertPathInvalid (doc , "[a]" , "path [[a]] is not valid" );
258+ assertPathInvalid (doc , "]a[" , "path []a[] is not valid" );
259+ assertPathInvalid (doc , "[]a" , "path [[]a] is not valid" );
260+ assertPathInvalid (doc , "][a" , "path [][a] is not valid" );
261+
262+ assertPathInvalid (doc , "a[0].b" , "path [a[0].b] is not valid" );
263+ assertPathInvalid (doc , "a[0].b[1]" , "path [a[0].b[1]] is not valid" );
264+ assertPathInvalid (doc , "a[0].b[1].c" , "path [a[0].b[1].c] is not valid" );
265+ assertPathInvalid (doc , "a[0].b[1].c[2]" , "path [a[0].b[1].c[2]] is not valid" );
266+ assertPathInvalid (doc , "a[0][1].c[2]" , "path [a[0][1].c[2]] is not valid" );
267+ assertPathInvalid (doc , "a[0].b[1][2]" , "path [a[0].b[1][2]] is not valid" );
268+ assertPathInvalid (doc , "a[0][1][2]" , "path [a[0][1][2]] is not valid" );
269+
270+ assertPathInvalid (doc , "a[0][" , "path [a[0][] is not valid" );
271+ assertPathInvalid (doc , "a[0]]" , "path [a[0]]] is not valid" );
272+ assertPathInvalid (doc , "a[0]blahblah" , "path [a[0]blahblah] is not valid" );
273+ });
274+ }
275+
192276 public void testSimpleGetFieldValue () throws Exception {
193277 doWithRandomAccessPattern ((doc ) -> {
194278 assertThat (doc .getFieldValue ("foo" , String .class ), equalTo ("bar" ));
0 commit comments