@@ -3,6 +3,9 @@ title: "Path expressions"
33sidebar_position : 41
44---
55
6+ import Tabs from '@theme/Tabs ';
7+ import TabItem from '@theme/TabItem ';
8+
69
710## What you will learn in this document
811- How to select specific fields or properties of a test object
@@ -19,6 +22,10 @@ As a beginner, think of path expressions as a way to "navigate" through your obj
1922
2023To understand path expressions, let's use a simple example object:
2124
25+
26+ <Tabs groupId =" language " >
27+ <TabItem value =" java " label =" Java " >
28+
2229``` java
2330@Value
2431public class JavaClass {
@@ -35,12 +42,33 @@ public class JavaClass {
3542}
3643```
3744
45+ </TabItem >
46+ <TabItem value =" kotlin " label =" Kotlin " >
47+
48+ ``` kotlin
49+ data class KotlinClass (
50+ val field : String ,
51+ val array : Array <String >,
52+ val list : List <String >,
53+ val `object `: Nested ,
54+ val objectList : List <Nested >
55+ ) {
56+ data class Nested (
57+ val nestedField : String
58+ )
59+ }
60+ ```
61+
62+ </TabItem >
63+ </Tabs >
64+
65+
3866## Visual Map of Path Expressions
3967
4068Think of your object as a tree structure. Each path expression is like directions to a specific location in that tree:
4169
4270```
43- JavaClass
71+ JavaClass / KotlinClass
4472│
4573├── field → "field" // Direct field access
4674│
@@ -70,149 +98,199 @@ JavaClass
7098
7199## Simple Path Expressions Guide
72100
101+ String path expressions work identically in Java and Kotlin. The examples below show both languages.
102+
73103### 1. Selecting the Root Object
74104
75- To select the entire object itself, use:
76- ``` java
77- " $"
78- ```
105+ To select the entire object itself, use ` "$" ` :
106+
107+
108+ <Tabs groupId =" language " >
109+ <TabItem value =" java " label =" Java " >
79110
80- ** Example:**
81111``` java
82112ArbitraryBuilder<JavaClass > builder = fixtureMonkey. giveMeBuilder(JavaClass . class);
83- // Select and manipulate the entire object
84113builder. set(" $" , new JavaClass (... ));
85114```
86115
87- ### 2. Selecting a Direct Field
116+ </TabItem >
117+ <TabItem value =" kotlin " label =" Kotlin " >
88118
89- To select a simple field at the top level:
90- ``` java
91- " field "
119+ ``` kotlin
120+ val builder = fixtureMonkey.giveMeBuilder< KotlinClass >()
121+ builder.set( " $ " , KotlinClass ( .. .))
92122```
93123
94- ** Example:**
124+ </TabItem >
125+ </Tabs >
126+
127+
128+ ### 2. Selecting a Direct Field
129+
130+
131+ <Tabs groupId =" language " >
132+ <TabItem value =" java " label =" Java " >
133+
95134``` java
96- // Set the "field" property to "Hello World"
97135builder. set(" field" , " Hello World" );
98136```
99137
100- ### 3. Selecting a Nested Field
138+ </TabItem >
139+ <TabItem value =" kotlin " label =" Kotlin " >
101140
102- To access a field inside a nested object:
103- ``` java
104- " object.nestedField"
141+ ``` kotlin
142+ builder.set(" field" , " Hello World" )
105143```
106144
107- ** Example:**
145+ </TabItem >
146+ </Tabs >
147+
148+
149+ ### 3. Selecting a Nested Field
150+
151+
152+ <Tabs groupId =" language " >
153+ <TabItem value =" java " label =" Java " >
154+
108155``` java
109- // Set the nestedField inside the object to "Nested Value"
110156builder. set(" object.nestedField" , " Nested Value" );
111157```
112158
113- ### 4. Working with Collections
159+ </TabItem >
160+ <TabItem value =" kotlin " label =" Kotlin " >
114161
115- #### Selecting a specific item in a list:
116- ``` java
117- " list[0]" // First item
118- " list[1]" // Second item
162+ ``` kotlin
163+ builder.set(" object.nestedField" , " Nested Value" )
119164```
120165
121- ** Example:**
166+ </TabItem >
167+ </Tabs >
168+
169+
170+ ### 4. Working with Collections
171+
172+
173+ <Tabs groupId =" language " >
174+ <TabItem value =" java " label =" Java " >
175+
122176``` java
123- // Set the first item in the list to "First Item"
177+ // Set the first item in the list
124178builder. set(" list[0]" , " First Item" );
125- ```
126179
127- #### Selecting ALL items in a list (wildcard):
128- ``` java
129- " list[*]"
180+ // Set ALL items in the list (wildcard)
181+ builder. set(" list[*]" , " Same Value" );
130182```
131183
132- ** Example:**
133- ``` java
134- // Set ALL items in the list to "Same Value"
135- builder. set(" list[*]" , " Same Value" );
184+ </TabItem >
185+ <TabItem value =" kotlin " label =" Kotlin " >
186+
187+ ``` kotlin
188+ // Set the first item in the list
189+ builder.set(" list[0]" , " First Item" )
190+
191+ // Set ALL items in the list (wildcard)
192+ builder.set(" list[*]" , " Same Value" )
136193```
137194
195+ </TabItem >
196+ </Tabs >
197+
198+
138199### 5. Working with Arrays
139200
140201Very similar to lists:
141202
203+
204+ <Tabs groupId =" language " >
205+ <TabItem value =" java " label =" Java " >
206+
142207``` java
143- " array[0]" // First element
144- " array[*]" // All elements
208+ builder . set( " array[0]" , " First Element " );
209+ builder . set( " array[*]" , " All Elements " );
145210```
146211
147- ** Example:**
148- ``` java
149- // Set all array elements to "Array Item"
150- builder. set(" array[*]" , " Array Item" );
212+ </TabItem >
213+ <TabItem value =" kotlin " label =" Kotlin " >
214+
215+ ``` kotlin
216+ builder.set(" array[0]" , " First Element" )
217+ builder.set(" array[*]" , " All Elements" )
151218```
152219
220+ </TabItem >
221+ </Tabs >
222+
223+
153224### 6. Complex Nested Paths
154225
155226You can combine these patterns to go as deep as you need:
156227
157- ``` java
158- " objectList[0].nestedField" // nestedField of first object in list
159- " objectList[*].nestedField" // nestedField of ALL objects in list
160- ```
161228
162- ** Example:**
229+ <Tabs groupId =" language " >
230+ <TabItem value =" java " label =" Java " >
231+
163232``` java
164- // Set the nestedField of all objects in objectList to "All Nested"
233+ // nestedField of first object in list
234+ builder. set(" objectList[0].nestedField" , " First Nested" );
235+
236+ // nestedField of ALL objects in list
165237builder. set(" objectList[*].nestedField" , " All Nested" );
166238```
167239
168- ## Type-Safe Selection with JavaGetter
169-
170- If you prefer to avoid string-based expressions, you can use type-safe getters:
240+ </TabItem >
241+ <TabItem value =" kotlin " label =" Kotlin " >
171242
172- ### 1. Selecting a Direct Field
243+ ``` kotlin
244+ // nestedField of first object in list
245+ builder.set(" objectList[0].nestedField" , " First Nested" )
173246
174- ``` java
175- javaGetter( JavaClass :: getField )
247+ // nestedField of ALL objects in list
248+ builder.set( " objectList[*].nestedField " , " All Nested " )
176249```
177250
178- ** Example:**
179- ``` java
180- builder. set(javaGetter(JavaClass :: getField), " Hello World" );
181- ```
251+ </TabItem >
252+ </Tabs >
182253
183- ### 2. Selecting a Nested Field
184254
185- ``` java
186- javaGetter(JavaClass :: getObject). into(Nested :: getNestedField)
187- ```
255+ ## Type-Safe Selection
256+
257+ ### Java: JavaGetter
258+
259+ If you prefer to avoid string-based expressions in Java, you can use type-safe getters:
188260
189- ** Example:**
190261``` java
262+ // Direct field
263+ builder. set(javaGetter(JavaClass :: getField), " Hello World" );
264+
265+ // Nested field
191266builder. set(
192- javaGetter(JavaClass :: getObject). into(Nested :: getNestedField),
267+ javaGetter(JavaClass :: getObject). into(Nested :: getNestedField),
193268 " Nested Value"
194269);
270+
271+ // Collection elements
272+ builder. set(javaGetter(JavaClass :: getList). index(String . class, 0 ), " First" );
273+ builder. set(javaGetter(JavaClass :: getList). allIndex(String . class), " All" );
195274```
196275
197- ### 3. Working with Collections
276+ ### Kotlin: DSL Exp
198277
199- ``` java
200- // Select specific element
201- javaGetter(JavaClass :: getList). index(String . class, 0 )
278+ Kotlin users can use property references for type-safe expressions:
202279
203- // Select all elements
204- javaGetter( JavaClass :: getList) . allIndex( String . class)
205- ```
280+ ``` kotlin
281+ // Direct field
282+ builder.setExp( KotlinClass ::field, " Hello World " )
206283
207- ** Example:**
208- ``` java
209- // Set all list elements to "List Item"
210- builder. set(
211- javaGetter(JavaClass :: getList). allIndex(String . class),
212- " List Item"
213- );
284+ // Nested field
285+ builder.setExp(KotlinClass ::`object ` into KotlinClass .Nested ::nestedField, " Nested Value" )
286+
287+ // Collection elements
288+ builder.setExp(KotlinClass ::objectList[" 0" ] into KotlinClass .Nested ::nestedField, " First" )
289+ builder.setExp(KotlinClass ::objectList[" *" ] into KotlinClass .Nested ::nestedField, " All" )
214290```
215291
292+ For more details on Kotlin DSL Expressions, see the [ Kotlin DSL Exp page] ( ../plugins/kotlin-plugin/kotlin-exp ) .
293+
216294## Common Beginner Questions
217295
218296### What happens if I try to access an out-of-bounds index?
@@ -225,7 +303,11 @@ While you can't directly access map elements with path expressions, you can use
225303
226304### Can I use multiple path expressions at once?
227305
228- Yes! You can chain multiple ` .set() ` calls to configure different parts of your object:
306+ Yes! You can chain multiple ` .set() ` calls:
307+
308+
309+ <Tabs groupId =" language " >
310+ <TabItem value =" java " label =" Java " >
229311
230312``` java
231313ArbitraryBuilder<JavaClass > builder = fixtureMonkey. giveMeBuilder(JavaClass . class)
@@ -234,6 +316,20 @@ ArbitraryBuilder<JavaClass> builder = fixtureMonkey.giveMeBuilder(JavaClass.clas
234316 .set(" list[*]" , " Value 3" );
235317```
236318
319+ </TabItem >
320+ <TabItem value =" kotlin " label =" Kotlin " >
321+
322+ ``` kotlin
323+ val builder = fixtureMonkey.giveMeBuilder<KotlinClass >()
324+ .set(" field" , " Value 1" )
325+ .set(" object.nestedField" , " Value 2" )
326+ .set(" list[*]" , " Value 3" )
327+ ```
328+
329+ </TabItem >
330+ </Tabs >
331+
332+
237333## Advanced Options
238334
239335### Expression Strict Mode
@@ -248,17 +344,6 @@ FixtureMonkey fixtureMonkey = FixtureMonkey.builder()
248344
249345With strict mode enabled, invalid paths will throw exceptions, helping you catch mistakes early.
250346
251- ### Kotlin Support
252-
253- If you're using Kotlin, you can use property references for even more elegant expressions:
254-
255- ``` kotlin
256- // Instead of: "user.address.street"
257- builder.setExp(User ::address into Address ::street, " Main Street" )
258- ```
259-
260- For more details, see the [ Kotlin DSL Exp page] ( ../plugins/kotlin-plugin/kotlin-exp ) .
261-
262347## Summary
263348
264349Path expressions are a powerful feature of Fixture Monkey that let you:
@@ -268,4 +353,3 @@ Path expressions are a powerful feature of Fixture Monkey that let you:
268353- Keep your test code clean and readable
269354
270355Start with simple direct field access, then gradually explore collection access and nested properties as you grow comfortable with the syntax.
271-
0 commit comments