Fork me on GitHub
#clojure-spec
<
2020-08-26
>
Aron08:08:36

What's the proper way to generate random emails for testing?

dharrigan08:08:11

If you're using spec you could use a generator

dharrigan08:08:30

shows one such approach

Aron08:08:24

Yes, I am trying to learn spec to use it : ) Would be a stretch that I am using it now : )

Aron08:08:14

I see, so these are valid emails but they only generate a relatively small subset of possible email formats

Joe Lane13:08:18

@ashnur Check out https://github.com/miner/strgen , ignoring that it still uses clojure.spec in it's examples, I think everything else should work.

👀 3
Aron13:08:02

I was just about to try test.chuck

Aron17:08:33

I tried out regal, and I like it, but I am not entirely sure I understand what is happening.I tried out regal, and I like it, but I am not entirely sure I understand what is happening.

Aron15:08:03

that link is broken 😞

Aron15:08:27

I am having an extremely frustrating experience while trying out test chuck. Even though the namespace is included, the example code doesn't work, methods like string-from-regexp are nil. I am not even sure in this situation where should I go to ask for help, probably #beginners ?

Alex Miller (Clojure team)15:08:42

here's probably fine - can you share a snippet of what you're doing?

Alex Miller (Clojure team)15:08:47

% clj -Sdeps '{:deps {com.gfredericks/test.chuck {:mvn/version "0.2.10"}}}'
Clojure 1.10.1
user=> (require '[com.gfredericks.test.chuck.generators :as gen'])
nil
user=> (require '[clojure.test.check.generators :as gen])
nil
user=> (gen/sample (gen'/string-from-regex #"([☃-♥]{3}|B(A|OO)M)*"))
("" "" "BAMBOOM" "♛♜☖☐♢☴♏♡♍" "☹♍♈☈☠♇BOOM" "BAMBAM♥♞☬♗☒☄" "" "BOOM" "♤☺☵☗☃☻BAM☨♥♗♕♥☈BOOMBOOM♊♅♝" "☪☓☉☠☓☔BOOM")

Aron15:08:57

so this only works with java I am guessing

Aron15:08:46

Probably because java regex is not the same as js regex. But then I am probably better off with one of the other options that were mentioned.

Alex Miller (Clojure team)15:08:52

it should work with both

Alex Miller (Clojure team)15:08:07

did you (require '[clojure.test.check.generators :as gen]) ?

Alex Miller (Clojure team)15:08:53

test.chuck builds on top of test.check, so you need to include both of the generator namespaces

Aron15:08:49

I did, but this gives me an idea

Alex Miller (Clojure team)16:08:02

it seems from those errors that you have issues with both the gen and gen' namespaces

hadils16:08:38

I need help with multi-spec:

(def a #{1 2 3})
(def b #{4 5 6})
(s/def ::type #{:foo :bar})
;;; This is pseudocode
(if (= ::type :foo)
   ; I want ::new-sym to be defined as a
  else (= ::type :bar)
    ; I want ::new-sym to be defined as b
; ::type and ::new-sym appear in the same map
I am pretty sure this is done with multi-spec but I am stumped as to how to make it work...

gfredericks16:08:12

test.chuck's regex generator is jvm-only

3
Alex Miller (Clojure team)16:08:29

@hadilsabbagh18 s/multi-spec is for the case where you can look at the data and return different specs based on the data

Alex Miller (Clojure team)16:08:35

what is your actual data?

Alex Miller (Clojure team)16:08:14

in general, spec is designed primarily for the case where attributes always have the same spec so you are probably going against that grain a bit.

Alex Miller (Clojure team)16:08:22

if the attribute is in a map, you could create (s/and (s/keys :req-un [::new-sym]) arbitrary-condition)) to tighten a more general spec

Alex Miller (Clojure team)16:08:49

and then use an s/multi-spec to choose which of those applies

hadils16:08:30

Thank you @alexmiller! Here is the actual snippet:

(s/def :budget-item/main-category #{"Household" "Personal" "Savings" "Investments" "Other"})

(defn budget-categories
  [main-category]
  (into #{}
    (mapv first
      (d/q '[:find ?cat :in $ ?main :where
             [?e :expense/budget-category ?main]
             [?e :expense/categories ?cat]] (db) main-category))))

(defmulti ordered-categories :budget-item/main-category)
(defmethod ordered-categories "Household" [_]
  (budget-categories "Household"))
(defmethod ordered-categories "Personal" [_]
  (budget-categories "Personal"))
(defmethod ordered-categories "Savings" [_]
  (budget-categories "Savings"))
(defmethod ordered-categories "Investments" [_]
  (budget-categories "Investments"))
(defmethod ordered-categories "Other" [_]
  (budget-categories "Other"))
(s/def :budget-item/ordered-categories (s/multi-spec ordered-categories ,,,))
I want to make :budget-item/ordered-categories dependent on what :budget-item/main-category is set to. They will be in a map together...

Alex Miller (Clojure team)17:08:24

yeah, I don't think you should do this in a spec

Alex Miller (Clojure team)17:08:27

or just make it a valid-category? predicate

Alex Miller (Clojure team)17:08:15

just spec ordered-categories as a string? or keyword? or whatever, then s/and the whole map predicate with a custom predicate that validates that extracts ordered-categories and main-category, and validates that one is valid according to the other

hadils17:08:55

Ok, I'll do that. Thanks a lot for your help @alexmiller! I am really grateful.

Alex Miller (Clojure team)17:08:41

dependent stuff is hard to do well - it's easiest to just specify that constraint at the level that contains all of the data