Created
October 4, 2017 14:13
-
-
Save conan/2edca210999b96ad26d38c1ee96dfe40 to your computer and use it in GitHub Desktop.
Clojure.spec URL and email specs with generators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(require '[cemerick.url :as url] | |
'[clojure.spec.alpha :as s] | |
'[clojure.spec.gen.alpha :as gen] | |
'[clojure.string :as string]) | |
(def non-empty-string-alphanumeric | |
"Generator for non-empty alphanumeric strings" | |
(gen/such-that #(not= "" %) | |
(gen/string-alphanumeric))) | |
(def non-empty-url-encoded-string | |
"Generator for url-encoded strings" | |
(gen/fmap | |
url/url-encode | |
(gen/such-that #(not= "" %) | |
(gen/string)))) | |
(def email-gen | |
"Generator for email addresses" | |
(gen/fmap | |
(fn [[name host tld]] | |
(str name "@" host "." tld)) | |
(gen/tuple | |
non-empty-string-alphanumeric | |
non-empty-string-alphanumeric | |
non-empty-string-alphanumeric))) | |
(def url-path-gen | |
"Generator that creates a string made up of one or more forward slash-separated non-empty strings" | |
(gen/fmap #(->> % | |
(map url/url-encode) | |
(interleave (repeat "/")) | |
(apply str)) | |
(gen/such-that #(not= [] %) | |
(gen/vector | |
(gen/such-that #(not= "" %) | |
(gen/string-alphanumeric)))))) | |
(def url-gen | |
"Generator for generating URLs; note that it may generate http URLs on port 443 and https URLs on port 80, | |
and that usernames and passwords only use alphanumerics" | |
(gen/fmap (partial apply (comp str url/->URL)) | |
(gen/tuple | |
;; protocol | |
(gen/elements #{"http" "https"}) | |
;; username | |
(gen/string-alphanumeric) | |
;; password | |
(gen/string-alphanumeric) | |
;; host | |
(gen/string-alphanumeric) | |
;; port | |
(gen/choose 1 65535) | |
;; path | |
url-path-gen | |
;; query | |
(gen/map | |
non-empty-url-encoded-string | |
non-empty-url-encoded-string | |
{:max-elements 10}) | |
;; anchor | |
(gen/fmap url/url-encode (gen/string))))) | |
(s/def ::email | |
(s/with-gen | |
#(re-matches #".+@.+\..+" %) | |
(fn [] email-gen))) | |
(s/def ::url | |
(s/with-gen | |
#(try (url/url %) (catch Throwable t false)) | |
(fn [] url-gen))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hope it helps! I love spec