Reputation: 299
I'm trying to use gen/fmap with two random alphanumeric strings. Then I concatenate them with "@" and append ".com". But I'm struggling with the syntax.
First attempt:
(gen/fmap str (gen/string-alphanumeric) "@" (gen/string-alphanumeric) ".com")
But gen/fmap only takes two arguments.
Second attempt, where I group the second part doesn't work either
(gen/fmap str ((gen/string-alphanumeric) "@" (gen/string-alphanumeric) ".com"))
EDIT: I have a partial solution. It generates an email address, but the part before and after the @ are the same. Example: [email protected]
This is the partial solution
(def gen-full-string
(gen/such-that #(not= % "") gen/string-alphanumeric))
(gen/fmap #(str % "@" % ".com") gen-full-string)
I wrote gen-full-string because the empty string ""
was crashing the code. Since I have parsing and plan to make validation functions, I didn't care about the empty string. I wanted to test core functionality not edge cases. Once I implement validation, I will probably remove gen-full-string. So the email generator would become (gen/fmap #(str % "@" % ".com") gen/string-alphanumeric)
Upvotes: 2
Views: 1344
Reputation: 1322
When I run this script:
clojure -Sdeps '{:deps {org.clojure/test.check {:mvn/version "1.1.0"}}}' /dev/stdin <<EOF
(require '[clojure.test.check.generators :as gen])
(def gen-email
(gen/fmap (fn [[s1 s2]] (format "%s@%s.com" s1 s2))
(gen/tuple gen/string-alphanumeric
gen/string-alphanumeric)))
(run! prn (gen/sample gen-email))
EOF
I get this output:
"@.com"
"@.com"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"[email protected]"
"@.com"
"[email protected]"
Upvotes: 3
Reputation: 6666
Gary Fredericks has a library https://github.com/gfredericks/test.chuck that adds string regex generation to Spec. This allows you to use a regex that is as simple or as detailed as you want for email addresses.
Upvotes: 4
Reputation: 29976
I like test.check
, but it takes a lot of time to understand the details. I created a helper library you may like. An example:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.gen :as tg]
[clojure.test.check.properties :as prop]
))
(dospec 9
(do
(newline)
(spy :sample)
(prop/for-all [w tg/word-alpha+]
(spyx w))))
(dospec 9
(do
(newline)
(spy :emails)
(prop/for-all [w1 tg/word-alpha+
w2 tg/word-alpha+]
(let [email-addr (str w1 \@ w2 ".com")]
(spyx email-addr)
)
)))
with result:
-----------------------------------
Clojure 1.10.3 Java 15.0.2
-----------------------------------
Testing tst.demo.core
:spy--tst.demo.core--line-011 => :sample
w => "b"
w => "lb"
w => "k"
w => "Y"
w => "mMWC"
w => "TzD"
w => "Nq"
w => "wQzPrF"
w => "HqEM"
{:result true, :num-tests 9, :seed 1629153846012, :time-elapsed-ms 1, :test-var "dospec-line-8"}
:spy--tst.demo.core--line-018 => :emails
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
email-addr => "[email protected]"
{:result true, :num-tests 9, :seed 1629153846014, :time-elapsed-ms 1, :test-var "dospec-line-15"}
More details here. The above example uses my favorite template project.
Upvotes: -2