Spesifikativ tugmachalarga har doim qanday ma'lumotlarni yaratish kerak?

Agar menga o'xshash spektakl bo'lsa

(clojure.spec/def ::person (clojure.spec/keys :req [::name ::address] :opt [::age]))

Va qilganda

(clojure.spec.gen/generate (clojure.spec/gen ::person))

Jenerator uchun ma'lumotlar ishlab chiqarilayotganda ixtiyoriy kalit (larni) ni har doim hisobga olishini aytishning biron bir usuli bormi?

Buni maxsus generatorlar bilan amalga oshirish mumkinligini bilaman, lekin men u uchun mavjud bo'lgan funktsiya mavjudligini yoki maxfiy generatorni belgilashni talab qilmaydigan sodda yondashuvni bilishni istadim.

0
Ha, qanday qiymatlar hosil qilinsa, barcha kalitlarga (ixtiyoriy, shu jumladan) ega bo'lishi kerak.
qo'shib qo'ydi muallif Punit Naik, manba
Ha, qanday qiymatlar hosil qilinsa, barcha kalitlarga (ixtiyoriy, shu jumladan) ega bo'lishi kerak.
qo'shib qo'ydi muallif Punit Naik, manba
Agar hammasi hosil qilingan qiymatlar ixtiyoriy tugmachalarni o'z ichiga olishi kerak bo'lsa, u holda tugmalar ixtiyoriy emas :-) Yoki boshqa yo'l bilan aytganda: ixtiyoriy tugmachalarga tegishli bo'lgan kod yo'lini sinab bo'lmaydi .
qo'shib qo'ydi muallif marco.m, manba
Agar hammasi hosil qilingan qiymatlar ixtiyoriy tugmachalarni o'z ichiga olishi kerak bo'lsa, u holda tugmalar ixtiyoriy emas :-) Yoki boshqa yo'l bilan aytganda: ixtiyoriy tugmachalarga tegishli bo'lgan kod yo'lini sinab bo'lmaydi .
qo'shib qo'ydi muallif marco.m, manba
hamma ixtiyoriy kalitlarga ega bo'lishi uchun hamma qiymatlarini yaratmoqchimisiz? Foydalanishingiz qanday? Buning bayrog'i bo'lsa men hayron bo'lardim.
qo'shib qo'ydi muallif gfredericks, manba
hamma ixtiyoriy kalitlarga ega bo'lishi uchun hamma qiymatlarini yaratmoqchimisiz? Foydalanishingiz qanday? Buning bayrog'i bo'lsa men hayron bo'lardim.
qo'shib qo'ydi muallif gfredericks, manba

5 javoblar

Sizning savolingizga qisqa javob "yo'q", deb o'ylayman, lekin ixtiyoriy tugmachalarni talab qiladigan spektakl bilan s/birlashma bo'lishi mumkin:

(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::person (s/keys :req [::name] :opt [::age]))

(gen/sample (s/gen ::person)) ;; ::age not always gen'd
(gen/sample                   ;; ::age always gen'd
  (s/gen (s/merge ::person (s/keys :req [::age]))))

Buni amalga oshiradigan s/keys spec w/generatorini yaratadigan so'lni yozishingiz mumkin.

3
qo'shib qo'ydi

Sizning savolingizga qisqa javob "yo'q", deb o'ylayman, lekin ixtiyoriy tugmachalarni talab qiladigan spektakl bilan s/birlashma bo'lishi mumkin:

(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::person (s/keys :req [::name] :opt [::age]))

(gen/sample (s/gen ::person)) ;; ::age not always gen'd
(gen/sample                   ;; ::age always gen'd
  (s/gen (s/merge ::person (s/keys :req [::age]))))

Buni amalga oshiradigan s/keys spec w/generatorini yaratadigan so'lni yozishingiz mumkin.

3
qo'shib qo'ydi

Menga yondoshish, bu spektaklning ( clojure.spec.alpha/form/) formasi orqali yurish edi, agar spektakl clojure.spec.alpha/kalitlari va nihoyat spec ni yangilang.

(defn merge-opt-keys
  "Merges optional keys into requried keys (for specs which are created using `clojure.spec.alpha/keys`) using a spec's form/description"
  [fspec]
  (let [keymap (into {} (map (fn [pair] (vec pair)) (partition 2 (rest fspec))))]
    (->> (cond-> {}
           (contains? keymap :opt)
             (assoc :req (vec (concat (keymap :req) (keymap :opt))))
           (contains? keymap :opt-un)
             (assoc :req-un (vec (concat (keymap :req-un) (keymap :opt-un)))))
         (mapcat identity)
         (cons 'clojure.spec.alpha/keys))))

(clojure.spec.alpha/def ::name string?)
(clojure.spec.alpha/def ::desc string?)
(clojure.spec.alpha/def ::book (clojure.spec.alpha/keys :req [::name] :opt [:desc]))

(clojure.spec.gen.alpha/generate (clojure.spec.alpha/gen (eval (merge-opt-keys (clojure.spec.alpha/form ::book)))))
0
qo'shib qo'ydi

Menga yondoshish, bu spektaklning ( clojure.spec.alpha/form/) formasi orqali yurish edi, agar spektakl clojure.spec.alpha/kalitlari va nihoyat spec ni yangilang.

(defn merge-opt-keys
  "Merges optional keys into requried keys (for specs which are created using `clojure.spec.alpha/keys`) using a spec's form/description"
  [fspec]
  (let [keymap (into {} (map (fn [pair] (vec pair)) (partition 2 (rest fspec))))]
    (->> (cond-> {}
           (contains? keymap :opt)
             (assoc :req (vec (concat (keymap :req) (keymap :opt))))
           (contains? keymap :opt-un)
             (assoc :req-un (vec (concat (keymap :req-un) (keymap :opt-un)))))
         (mapcat identity)
         (cons 'clojure.spec.alpha/keys))))

(clojure.spec.alpha/def ::name string?)
(clojure.spec.alpha/def ::desc string?)
(clojure.spec.alpha/def ::book (clojure.spec.alpha/keys :req [::name] :opt [:desc]))

(clojure.spec.gen.alpha/generate (clojure.spec.alpha/gen (eval (merge-opt-keys (clojure.spec.alpha/form ::book)))))
0
qo'shib qo'ydi

Menga yondoshish, bu spektaklning ( clojure.spec.alpha/form/) formasi orqali yurish edi, agar spektakl clojure.spec.alpha/kalitlari va nihoyat spec ni yangilang.

(defn merge-opt-keys
  "Merges optional keys into requried keys (for specs which are created using `clojure.spec.alpha/keys`) using a spec's form/description"
  [fspec]
  (let [keymap (into {} (map (fn [pair] (vec pair)) (partition 2 (rest fspec))))]
    (->> (cond-> {}
           (contains? keymap :opt)
             (assoc :req (vec (concat (keymap :req) (keymap :opt))))
           (contains? keymap :opt-un)
             (assoc :req-un (vec (concat (keymap :req-un) (keymap :opt-un)))))
         (mapcat identity)
         (cons 'clojure.spec.alpha/keys))))

(clojure.spec.alpha/def ::name string?)
(clojure.spec.alpha/def ::desc string?)
(clojure.spec.alpha/def ::book (clojure.spec.alpha/keys :req [::name] :opt [:desc]))

(clojure.spec.gen.alpha/generate (clojure.spec.alpha/gen (eval (merge-opt-keys (clojure.spec.alpha/form ::book)))))
0
qo'shib qo'ydi