Let's say we have API to save different type of files' attributes into DB*: text, images, audio and video files. It should be able to get the following fields based on their type:
base properties for all the files:
{"file-type": "text",
"location": "/Documents",
"creation-time": "2020-03-02",
"name": "sometext.txt"}
additional props specific only for some types:
text: only base props
video file: base props + {"duration(s)":123, "resolution":"4k"}
audio file: base props + {"duration(s)":123}
image: base props + {"resolution":"2048x1536"}
as we can see, some fields should be nil depenping on "file-type". Let's say we need to validate this kind of input, which it can be any type of the described. So the specs are:
(s/def ::file-type (s/with-gen (s/and string? not-empty) #(s/gen #{"text" "image" "video" "audio"})))
(s/def ::location (s/with-gen (s/and string? not-empty) #(s/gen #{"/Documents"})))
(s/def ::creation-time (s/with-gen (s/and string? not-empty) #(s/gen #{"2020-03-02"}))) ;for simplicity
(s/def ::name (s/with-gen (s/and string? not-empty) #(s/gen #{"sometext.txt" "image.jpg" "video.mp4" "audio.mp3"}))) ;for simplicity
(s/def ::duration (s/and int? not-empty)) ;for simplicity
(s/def ::resolution (s/with-gen (s/and string? not-empty) #(s/gen #{"4k" "2048x1536"}))) ;for simplicity
(s/def ::files-input (s/keys :req-un [::file-type ::location ::creation-time ::extension] :opt-un [::duration ::resolution]))
Let's also say that there is a programmatic validator that checks the right field set was passed for each file type (e.g., "video" has "duration" field, but "text" has not).
The question is: how to generate the full ready-made input with those dependencies for unit-tests (including the dependant fields)?
*(let's leave aside the question if it is a right design for API as this example is not from real life and for demonstration purpose only)