Допустим, у нас есть API для сохранения различных типов атрибутов файлов в БД *: текстовых, графических, аудио- и видеофайлов. Он должен иметь возможность получать следующие поля в зависимости от их типа:
базовые свойства для всех файлов:
{"file-type": "text",
"location": "/Documents",
"creation-time": "2020-03-02",
"name": "sometext.txt"}
дополнительные реквизиты, указанные c только для некоторых типов:
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"}
как мы видим, некоторые поля должны быть нулевыми, в зависимости от типа файла. Допустим, нам нужно проверить ввод такого рода, который может быть любым из описанных. Итак, спецификации таковы:
(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]))
Скажем также, что существует программный валидатор c, который проверяет, был ли передан правильный набор полей для каждого типа файла (например, «video» имеет поле «duration», но «текст» не имеет).
Вопрос заключается в следующем: как создать полный готовый ввод с этими зависимостями для юнит-тестов (включая зависимые поля)?
* (давайте оставим в стороне вопрос, является ли это правильным дизайном для API, поскольку этот пример не из реальной жизни и только для демонстрационных целей)