aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/atoms/alnum.test.py26
-rw-r--r--tests/atoms/ascii.test.py26
-rw-r--r--tests/atoms/base32.test.py26
-rw-r--r--tests/atoms/base58.test.py26
-rw-r--r--tests/atoms/base64.test.py26
-rw-r--r--tests/atoms/base64url.test.py26
-rw-r--r--tests/atoms/bic.test.py26
-rw-r--r--tests/atoms/binnum.test.py26
-rw-r--r--tests/atoms/boolean.test.py26
-rw-r--r--tests/atoms/braces.test.py26
-rw-r--r--tests/atoms/brackets.test.py26
-rw-r--r--tests/atoms/cidr.test.py26
-rw-r--r--tests/atoms/clock.test.py26
-rw-r--r--tests/atoms/clock12.test.py26
-rw-r--r--tests/atoms/creditcard.test.py26
-rw-r--r--tests/atoms/currency.test.py26
-rw-r--r--tests/atoms/day.test.py26
-rw-r--r--tests/atoms/decimal.test.py26
-rw-r--r--tests/atoms/duration.test.py26
-rw-r--r--tests/atoms/email.test.py26
-rw-r--r--tests/atoms/epoch.test.py26
-rw-r--r--tests/atoms/extension.test.py26
-rw-r--r--tests/atoms/filename.test.py26
-rw-r--r--tests/atoms/filepath.test.py26
-rw-r--r--tests/atoms/floatnum.test.py26
-rw-r--r--tests/atoms/guid.test.py26
-rw-r--r--tests/atoms/hexcolor.test.py26
-rw-r--r--tests/atoms/hexnum.test.py26
-rw-r--r--tests/atoms/hexstring.test.py26
-rw-r--r--tests/atoms/hostname.test.py26
-rw-r--r--tests/atoms/httpmethod.test.py26
-rw-r--r--tests/atoms/httpstatus.test.py26
-rw-r--r--tests/atoms/iban.test.py26
-rw-r--r--tests/atoms/integer.test.py26
-rw-r--r--tests/atoms/ipv4.test.py26
-rw-r--r--tests/atoms/ipv6.test.py26
-rw-r--r--tests/atoms/isodate.test.py26
-rw-r--r--tests/atoms/isodatetime.test.py26
-rw-r--r--tests/atoms/label.test.py26
-rw-r--r--tests/atoms/letter.test.py26
-rw-r--r--tests/atoms/line.test.py26
-rw-r--r--tests/atoms/localpart.test.py26
-rw-r--r--tests/atoms/lower.test.py26
-rw-r--r--tests/atoms/mac.test.py26
-rw-r--r--tests/atoms/md5.test.py26
-rw-r--r--tests/atoms/mimetype.test.py26
-rw-r--r--tests/atoms/money.test.py26
-rw-r--r--tests/atoms/month.test.py26
-rw-r--r--tests/atoms/natural.test.py26
-rw-r--r--tests/atoms/nibble.test.py26
-rw-r--r--tests/atoms/objectid.test.py26
-rw-r--r--tests/atoms/octet.test.py26
-rw-r--r--tests/atoms/octnum.test.py26
-rw-r--r--tests/atoms/oid.test.py26
-rw-r--r--tests/atoms/parens.test.py26
-rw-r--r--tests/atoms/percent.test.py26
-rw-r--r--tests/atoms/port.test.py26
-rw-r--r--tests/atoms/printable.test.py26
-rw-r--r--tests/atoms/protocol.test.py26
-rw-r--r--tests/atoms/quoted.test.py26
-rw-r--r--tests/atoms/ratio.test.py26
-rw-r--r--tests/atoms/rgbcolor.test.py26
-rw-r--r--tests/atoms/scheme.test.py26
-rw-r--r--tests/atoms/scientific.test.py26
-rw-r--r--tests/atoms/semver.test.py26
-rw-r--r--tests/atoms/sha256.test.py26
-rw-r--r--tests/atoms/signed.test.py26
-rw-r--r--tests/atoms/slug.test.py26
-rw-r--r--tests/atoms/space.test.py26
-rw-r--r--tests/atoms/timezone.test.py26
-rw-r--r--tests/atoms/tld.test.py26
-rw-r--r--tests/atoms/truefalse.test.py26
-rw-r--r--tests/atoms/ulid.test.py26
-rw-r--r--tests/atoms/unsigned.test.py26
-rw-r--r--tests/atoms/upper.test.py26
-rw-r--r--tests/atoms/uri.test.py26
-rw-r--r--tests/atoms/url.test.py26
-rw-r--r--tests/atoms/username.test.py26
-rw-r--r--tests/atoms/uuid.test.py26
-rw-r--r--tests/atoms/weekday.test.py26
-rw-r--r--tests/atoms/word.test.py26
-rw-r--r--tests/atoms/year.test.py26
-rw-r--r--tests/atoms/yesno.test.py26
83 files changed, 2158 insertions, 0 deletions
diff --git a/tests/atoms/alnum.test.py b/tests/atoms/alnum.test.py
new file mode 100644
index 0000000..3e3e6c0
--- /dev/null
+++ b/tests/atoms/alnum.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import alnum
+
+
+def _anchored():
+ return Pattern().start_of_input().use(alnum).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("!")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(alnum).end_of_input()
+ assert embedded("v=" + "a")
+ assert not embedded("a")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = alnum.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/ascii.test.py b/tests/atoms/ascii.test.py
new file mode 100644
index 0000000..4f94b0f
--- /dev/null
+++ b/tests/atoms/ascii.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import ascii
+
+
+def _anchored():
+ return Pattern().start_of_input().use(ascii).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("☃")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(ascii).end_of_input()
+ assert embedded("v=" + "a")
+ assert not embedded("a")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = ascii.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/base32.test.py b/tests/atoms/base32.test.py
new file mode 100644
index 0000000..b55df31
--- /dev/null
+++ b/tests/atoms/base32.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import base32
+
+
+def _anchored():
+ return Pattern().start_of_input().use(base32).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("JBSWY3DP===")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("lower")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(base32).end_of_input()
+ assert embedded("v=" + "JBSWY3DP===")
+ assert not embedded("JBSWY3DP===")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = base32.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/base58.test.py b/tests/atoms/base58.test.py
new file mode 100644
index 0000000..7af4b1c
--- /dev/null
+++ b/tests/atoms/base58.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import base58
+
+
+def _anchored():
+ return Pattern().start_of_input().use(base58).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("3P3Ceff5tj")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("0")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(base58).end_of_input()
+ assert embedded("v=" + "3P3Ceff5tj")
+ assert not embedded("3P3Ceff5tj")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = base58.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/base64.test.py b/tests/atoms/base64.test.py
new file mode 100644
index 0000000..03ada86
--- /dev/null
+++ b/tests/atoms/base64.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import base64
+
+
+def _anchored():
+ return Pattern().start_of_input().use(base64).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("SGVsbG8=")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("!!")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(base64).end_of_input()
+ assert embedded("v=" + "SGVsbG8=")
+ assert not embedded("SGVsbG8=")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = base64.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/base64url.test.py b/tests/atoms/base64url.test.py
new file mode 100644
index 0000000..51a7bf3
--- /dev/null
+++ b/tests/atoms/base64url.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import base64url
+
+
+def _anchored():
+ return Pattern().start_of_input().use(base64url).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("Hello_World-")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("!")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(base64url).end_of_input()
+ assert embedded("v=" + "Hello_World-")
+ assert not embedded("Hello_World-")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = base64url.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/bic.test.py b/tests/atoms/bic.test.py
new file mode 100644
index 0000000..ba92236
--- /dev/null
+++ b/tests/atoms/bic.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import bic
+
+
+def _anchored():
+ return Pattern().start_of_input().use(bic).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("DEUTDEFF500")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(bic).end_of_input()
+ assert embedded("v=" + "DEUTDEFF500")
+ assert not embedded("DEUTDEFF500")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = bic.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/binnum.test.py b/tests/atoms/binnum.test.py
new file mode 100644
index 0000000..4018823
--- /dev/null
+++ b/tests/atoms/binnum.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import binnum
+
+
+def _anchored():
+ return Pattern().start_of_input().use(binnum).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("0b1010")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1010")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(binnum).end_of_input()
+ assert embedded("v=" + "0b1010")
+ assert not embedded("0b1010")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = binnum.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/boolean.test.py b/tests/atoms/boolean.test.py
new file mode 100644
index 0000000..9b629c6
--- /dev/null
+++ b/tests/atoms/boolean.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import boolean
+
+
+def _anchored():
+ return Pattern().start_of_input().use(boolean).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("on")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("maybe")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(boolean).end_of_input()
+ assert embedded("v=" + "on")
+ assert not embedded("on")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = boolean.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/braces.test.py b/tests/atoms/braces.test.py
new file mode 100644
index 0000000..85cda16
--- /dev/null
+++ b/tests/atoms/braces.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import braces
+
+
+def _anchored():
+ return Pattern().start_of_input().use(braces).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("{hello}")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("hello")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(braces).end_of_input()
+ assert embedded("v=" + "{hello}")
+ assert not embedded("{hello}")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = braces.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/brackets.test.py b/tests/atoms/brackets.test.py
new file mode 100644
index 0000000..0bdf41c
--- /dev/null
+++ b/tests/atoms/brackets.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import brackets
+
+
+def _anchored():
+ return Pattern().start_of_input().use(brackets).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("[hello]")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("hello")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(brackets).end_of_input()
+ assert embedded("v=" + "[hello]")
+ assert not embedded("[hello]")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = brackets.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/cidr.test.py b/tests/atoms/cidr.test.py
new file mode 100644
index 0000000..a7dc9c9
--- /dev/null
+++ b/tests/atoms/cidr.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import cidr
+
+
+def _anchored():
+ return Pattern().start_of_input().use(cidr).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("10.0.0.0/8")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("10.0.0.0")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(cidr).end_of_input()
+ assert embedded("v=" + "10.0.0.0/8")
+ assert not embedded("10.0.0.0/8")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = cidr.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/clock.test.py b/tests/atoms/clock.test.py
new file mode 100644
index 0000000..2abe10a
--- /dev/null
+++ b/tests/atoms/clock.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import clock
+
+
+def _anchored():
+ return Pattern().start_of_input().use(clock).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("23:59")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("24:00")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(clock).end_of_input()
+ assert embedded("v=" + "23:59")
+ assert not embedded("23:59")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = clock.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/clock12.test.py b/tests/atoms/clock12.test.py
new file mode 100644
index 0000000..528eae5
--- /dev/null
+++ b/tests/atoms/clock12.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import clock12
+
+
+def _anchored():
+ return Pattern().start_of_input().use(clock12).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("12:00 PM")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("13:00 PM")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(clock12).end_of_input()
+ assert embedded("v=" + "12:00 PM")
+ assert not embedded("12:00 PM")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = clock12.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/creditcard.test.py b/tests/atoms/creditcard.test.py
new file mode 100644
index 0000000..a436d2c
--- /dev/null
+++ b/tests/atoms/creditcard.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import creditcard
+
+
+def _anchored():
+ return Pattern().start_of_input().use(creditcard).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("4111111111111111")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("abc")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(creditcard).end_of_input()
+ assert embedded("v=" + "4111111111111111")
+ assert not embedded("4111111111111111")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = creditcard.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/currency.test.py b/tests/atoms/currency.test.py
new file mode 100644
index 0000000..21fa483
--- /dev/null
+++ b/tests/atoms/currency.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import currency
+
+
+def _anchored():
+ return Pattern().start_of_input().use(currency).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("USD")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("us")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(currency).end_of_input()
+ assert embedded("v=" + "USD")
+ assert not embedded("USD")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = currency.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/day.test.py b/tests/atoms/day.test.py
new file mode 100644
index 0000000..c751b94
--- /dev/null
+++ b/tests/atoms/day.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import day
+
+
+def _anchored():
+ return Pattern().start_of_input().use(day).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("15")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("32")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(day).end_of_input()
+ assert embedded("v=" + "15")
+ assert not embedded("15")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = day.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/decimal.test.py b/tests/atoms/decimal.test.py
new file mode 100644
index 0000000..13140c6
--- /dev/null
+++ b/tests/atoms/decimal.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import decimal
+
+
+def _anchored():
+ return Pattern().start_of_input().use(decimal).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("3.14")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("3")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(decimal).end_of_input()
+ assert embedded("v=" + "3.14")
+ assert not embedded("3.14")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = decimal.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/duration.test.py b/tests/atoms/duration.test.py
new file mode 100644
index 0000000..5f362c9
--- /dev/null
+++ b/tests/atoms/duration.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import duration
+
+
+def _anchored():
+ return Pattern().start_of_input().use(duration).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("P1Y")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("P")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(duration).end_of_input()
+ assert embedded("v=" + "P1Y")
+ assert not embedded("P1Y")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = duration.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/email.test.py b/tests/atoms/email.test.py
new file mode 100644
index 0000000..24fa895
--- /dev/null
+++ b/tests/atoms/email.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import email
+
+
+def _anchored():
+ return Pattern().start_of_input().use(email).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("[email protected]")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("not email")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(email).end_of_input()
+ assert embedded("v=" + "[email protected]")
+ assert not embedded("[email protected]")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = email.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/epoch.test.py b/tests/atoms/epoch.test.py
new file mode 100644
index 0000000..8be01e6
--- /dev/null
+++ b/tests/atoms/epoch.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import epoch
+
+
+def _anchored():
+ return Pattern().start_of_input().use(epoch).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("1704067200")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("12")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(epoch).end_of_input()
+ assert embedded("v=" + "1704067200")
+ assert not embedded("1704067200")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = epoch.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/extension.test.py b/tests/atoms/extension.test.py
new file mode 100644
index 0000000..5374e60
--- /dev/null
+++ b/tests/atoms/extension.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import extension
+
+
+def _anchored():
+ return Pattern().start_of_input().use(extension).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()(".txt")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("txt")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(extension).end_of_input()
+ assert embedded("v=" + ".txt")
+ assert not embedded(".txt")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = extension.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/filename.test.py b/tests/atoms/filename.test.py
new file mode 100644
index 0000000..c33840b
--- /dev/null
+++ b/tests/atoms/filename.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import filename
+
+
+def _anchored():
+ return Pattern().start_of_input().use(filename).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("myfile.txt")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad/path")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(filename).end_of_input()
+ assert embedded("v=" + "myfile.txt")
+ assert not embedded("myfile.txt")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = filename.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/filepath.test.py b/tests/atoms/filepath.test.py
new file mode 100644
index 0000000..4ea3552
--- /dev/null
+++ b/tests/atoms/filepath.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import filepath
+
+
+def _anchored():
+ return Pattern().start_of_input().use(filepath).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("/home/user")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(filepath).end_of_input()
+ assert embedded("v=" + "/home/user")
+ assert not embedded("/home/user")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = filepath.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/floatnum.test.py b/tests/atoms/floatnum.test.py
new file mode 100644
index 0000000..13bd114
--- /dev/null
+++ b/tests/atoms/floatnum.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import floatnum
+
+
+def _anchored():
+ return Pattern().start_of_input().use(floatnum).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("1.5e10")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("abc")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(floatnum).end_of_input()
+ assert embedded("v=" + "1.5e10")
+ assert not embedded("1.5e10")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = floatnum.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/guid.test.py b/tests/atoms/guid.test.py
new file mode 100644
index 0000000..45d2446
--- /dev/null
+++ b/tests/atoms/guid.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import guid
+
+
+def _anchored():
+ return Pattern().start_of_input().use(guid).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("550e8400-e29b-11d4-a716-446655440000")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(guid).end_of_input()
+ assert embedded("v=" + "550e8400-e29b-11d4-a716-446655440000")
+ assert not embedded("550e8400-e29b-11d4-a716-446655440000")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = guid.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/hexcolor.test.py b/tests/atoms/hexcolor.test.py
new file mode 100644
index 0000000..6dbd865
--- /dev/null
+++ b/tests/atoms/hexcolor.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import hexcolor
+
+
+def _anchored():
+ return Pattern().start_of_input().use(hexcolor).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("#abc")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("nope")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(hexcolor).end_of_input()
+ assert embedded("v=" + "#abc")
+ assert not embedded("#abc")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = hexcolor.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/hexnum.test.py b/tests/atoms/hexnum.test.py
new file mode 100644
index 0000000..20c8d16
--- /dev/null
+++ b/tests/atoms/hexnum.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import hexnum
+
+
+def _anchored():
+ return Pattern().start_of_input().use(hexnum).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("0xFF")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("FF")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(hexnum).end_of_input()
+ assert embedded("v=" + "0xFF")
+ assert not embedded("0xFF")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = hexnum.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/hexstring.test.py b/tests/atoms/hexstring.test.py
new file mode 100644
index 0000000..c1a53b4
--- /dev/null
+++ b/tests/atoms/hexstring.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import hexstring
+
+
+def _anchored():
+ return Pattern().start_of_input().use(hexstring).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("deadbeef")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("z")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(hexstring).end_of_input()
+ assert embedded("v=" + "deadbeef")
+ assert not embedded("deadbeef")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = hexstring.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/hostname.test.py b/tests/atoms/hostname.test.py
new file mode 100644
index 0000000..1fdd883
--- /dev/null
+++ b/tests/atoms/hostname.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import hostname
+
+
+def _anchored():
+ return Pattern().start_of_input().use(hostname).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a.b.c")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("-nope")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(hostname).end_of_input()
+ assert embedded("v=" + "a.b.c")
+ assert not embedded("a.b.c")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = hostname.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/httpmethod.test.py b/tests/atoms/httpmethod.test.py
new file mode 100644
index 0000000..c77c973
--- /dev/null
+++ b/tests/atoms/httpmethod.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import httpmethod
+
+
+def _anchored():
+ return Pattern().start_of_input().use(httpmethod).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("POST")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("FOO")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(httpmethod).end_of_input()
+ assert embedded("v=" + "POST")
+ assert not embedded("POST")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = httpmethod.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/httpstatus.test.py b/tests/atoms/httpstatus.test.py
new file mode 100644
index 0000000..d26ac40
--- /dev/null
+++ b/tests/atoms/httpstatus.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import httpstatus
+
+
+def _anchored():
+ return Pattern().start_of_input().use(httpstatus).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("200")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("600")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(httpstatus).end_of_input()
+ assert embedded("v=" + "200")
+ assert not embedded("200")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = httpstatus.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/iban.test.py b/tests/atoms/iban.test.py
new file mode 100644
index 0000000..3966f5f
--- /dev/null
+++ b/tests/atoms/iban.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import iban
+
+
+def _anchored():
+ return Pattern().start_of_input().use(iban).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("GB33BUKB20201555555555")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(iban).end_of_input()
+ assert embedded("v=" + "GB33BUKB20201555555555")
+ assert not embedded("GB33BUKB20201555555555")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = iban.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/integer.test.py b/tests/atoms/integer.test.py
new file mode 100644
index 0000000..d5e9fa8
--- /dev/null
+++ b/tests/atoms/integer.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import integer
+
+
+def _anchored():
+ return Pattern().start_of_input().use(integer).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("-42")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("abc")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(integer).end_of_input()
+ assert embedded("v=" + "-42")
+ assert not embedded("-42")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = integer.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/ipv4.test.py b/tests/atoms/ipv4.test.py
new file mode 100644
index 0000000..f55033d
--- /dev/null
+++ b/tests/atoms/ipv4.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import ipv4
+
+
+def _anchored():
+ return Pattern().start_of_input().use(ipv4).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("192.168.1.1")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("999.0.0.0")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(ipv4).end_of_input()
+ assert embedded("v=" + "192.168.1.1")
+ assert not embedded("192.168.1.1")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = ipv4.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/ipv6.test.py b/tests/atoms/ipv6.test.py
new file mode 100644
index 0000000..300bb09
--- /dev/null
+++ b/tests/atoms/ipv6.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import ipv6
+
+
+def _anchored():
+ return Pattern().start_of_input().use(ipv6).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("2001:db8:0:0:0:0:0:1")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("not_ipv6")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(ipv6).end_of_input()
+ assert embedded("v=" + "2001:db8:0:0:0:0:0:1")
+ assert not embedded("2001:db8:0:0:0:0:0:1")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = ipv6.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/isodate.test.py b/tests/atoms/isodate.test.py
new file mode 100644
index 0000000..aefb79a
--- /dev/null
+++ b/tests/atoms/isodate.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import isodate
+
+
+def _anchored():
+ return Pattern().start_of_input().use(isodate).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("2024-01-15")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("2024/01/15")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(isodate).end_of_input()
+ assert embedded("v=" + "2024-01-15")
+ assert not embedded("2024-01-15")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = isodate.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/isodatetime.test.py b/tests/atoms/isodatetime.test.py
new file mode 100644
index 0000000..78aa769
--- /dev/null
+++ b/tests/atoms/isodatetime.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import isodatetime
+
+
+def _anchored():
+ return Pattern().start_of_input().use(isodatetime).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("2024-01-15T12:00:00Z")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(isodatetime).end_of_input()
+ assert embedded("v=" + "2024-01-15T12:00:00Z")
+ assert not embedded("2024-01-15T12:00:00Z")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = isodatetime.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/label.test.py b/tests/atoms/label.test.py
new file mode 100644
index 0000000..ba16b34
--- /dev/null
+++ b/tests/atoms/label.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import label
+
+
+def _anchored():
+ return Pattern().start_of_input().use(label).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("example")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("-bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(label).end_of_input()
+ assert embedded("v=" + "example")
+ assert not embedded("example")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = label.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/letter.test.py b/tests/atoms/letter.test.py
new file mode 100644
index 0000000..481032d
--- /dev/null
+++ b/tests/atoms/letter.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import letter
+
+
+def _anchored():
+ return Pattern().start_of_input().use(letter).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(letter).end_of_input()
+ assert embedded("v=" + "a")
+ assert not embedded("a")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = letter.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/line.test.py b/tests/atoms/line.test.py
new file mode 100644
index 0000000..a0f7b09
--- /dev/null
+++ b/tests/atoms/line.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import line
+
+
+def _anchored():
+ return Pattern().start_of_input().use(line).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("hello world")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("\n")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(line).end_of_input()
+ assert embedded("v=" + "hello world")
+ assert not embedded("hello world")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = line.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/localpart.test.py b/tests/atoms/localpart.test.py
new file mode 100644
index 0000000..51003ca
--- /dev/null
+++ b/tests/atoms/localpart.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import localpart
+
+
+def _anchored():
+ return Pattern().start_of_input().use(localpart).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("user.name")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(localpart).end_of_input()
+ assert embedded("v=" + "user.name")
+ assert not embedded("user.name")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = localpart.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/lower.test.py b/tests/atoms/lower.test.py
new file mode 100644
index 0000000..0b947a8
--- /dev/null
+++ b/tests/atoms/lower.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import lower
+
+
+def _anchored():
+ return Pattern().start_of_input().use(lower).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("A")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(lower).end_of_input()
+ assert embedded("v=" + "a")
+ assert not embedded("a")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = lower.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/mac.test.py b/tests/atoms/mac.test.py
new file mode 100644
index 0000000..21a1084
--- /dev/null
+++ b/tests/atoms/mac.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import mac
+
+
+def _anchored():
+ return Pattern().start_of_input().use(mac).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("aa:bb:cc:dd:ee:ff")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("not-a-mac")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(mac).end_of_input()
+ assert embedded("v=" + "aa:bb:cc:dd:ee:ff")
+ assert not embedded("aa:bb:cc:dd:ee:ff")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = mac.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/md5.test.py b/tests/atoms/md5.test.py
new file mode 100644
index 0000000..4dd99e3
--- /dev/null
+++ b/tests/atoms/md5.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import md5
+
+
+def _anchored():
+ return Pattern().start_of_input().use(md5).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("short")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(md5).end_of_input()
+ assert embedded("v=" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+ assert not embedded("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = md5.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/mimetype.test.py b/tests/atoms/mimetype.test.py
new file mode 100644
index 0000000..267d3eb
--- /dev/null
+++ b/tests/atoms/mimetype.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import mimetype
+
+
+def _anchored():
+ return Pattern().start_of_input().use(mimetype).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("text/plain")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("text")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(mimetype).end_of_input()
+ assert embedded("v=" + "text/plain")
+ assert not embedded("text/plain")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = mimetype.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/money.test.py b/tests/atoms/money.test.py
new file mode 100644
index 0000000..edaebee
--- /dev/null
+++ b/tests/atoms/money.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import money
+
+
+def _anchored():
+ return Pattern().start_of_input().use(money).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("USD 100.50")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(money).end_of_input()
+ assert embedded("v=" + "USD 100.50")
+ assert not embedded("USD 100.50")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = money.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/month.test.py b/tests/atoms/month.test.py
new file mode 100644
index 0000000..a1dcd99
--- /dev/null
+++ b/tests/atoms/month.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import month
+
+
+def _anchored():
+ return Pattern().start_of_input().use(month).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("07")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("13")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(month).end_of_input()
+ assert embedded("v=" + "07")
+ assert not embedded("07")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = month.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/natural.test.py b/tests/atoms/natural.test.py
new file mode 100644
index 0000000..d5f61d2
--- /dev/null
+++ b/tests/atoms/natural.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import natural
+
+
+def _anchored():
+ return Pattern().start_of_input().use(natural).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("42")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("07")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(natural).end_of_input()
+ assert embedded("v=" + "42")
+ assert not embedded("42")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = natural.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/nibble.test.py b/tests/atoms/nibble.test.py
new file mode 100644
index 0000000..94f39c8
--- /dev/null
+++ b/tests/atoms/nibble.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import nibble
+
+
+def _anchored():
+ return Pattern().start_of_input().use(nibble).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("a")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("g")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(nibble).end_of_input()
+ assert embedded("v=" + "a")
+ assert not embedded("a")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = nibble.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/objectid.test.py b/tests/atoms/objectid.test.py
new file mode 100644
index 0000000..b8ce687
--- /dev/null
+++ b/tests/atoms/objectid.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import objectid
+
+
+def _anchored():
+ return Pattern().start_of_input().use(objectid).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("507f1f77bcf86cd799439011")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("short")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(objectid).end_of_input()
+ assert embedded("v=" + "507f1f77bcf86cd799439011")
+ assert not embedded("507f1f77bcf86cd799439011")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = objectid.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/octet.test.py b/tests/atoms/octet.test.py
new file mode 100644
index 0000000..00985b2
--- /dev/null
+++ b/tests/atoms/octet.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import octet
+
+
+def _anchored():
+ return Pattern().start_of_input().use(octet).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("192")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("999")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(octet).end_of_input()
+ assert embedded("v=" + "192")
+ assert not embedded("192")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = octet.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/octnum.test.py b/tests/atoms/octnum.test.py
new file mode 100644
index 0000000..a7a0106
--- /dev/null
+++ b/tests/atoms/octnum.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import octnum
+
+
+def _anchored():
+ return Pattern().start_of_input().use(octnum).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("0o17")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("17")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(octnum).end_of_input()
+ assert embedded("v=" + "0o17")
+ assert not embedded("0o17")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = octnum.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/oid.test.py b/tests/atoms/oid.test.py
new file mode 100644
index 0000000..0c8182a
--- /dev/null
+++ b/tests/atoms/oid.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import oid
+
+
+def _anchored():
+ return Pattern().start_of_input().use(oid).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("1.3.6.1.4.1")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(oid).end_of_input()
+ assert embedded("v=" + "1.3.6.1.4.1")
+ assert not embedded("1.3.6.1.4.1")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = oid.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/parens.test.py b/tests/atoms/parens.test.py
new file mode 100644
index 0000000..e9d07a3
--- /dev/null
+++ b/tests/atoms/parens.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import parens
+
+
+def _anchored():
+ return Pattern().start_of_input().use(parens).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("(hello)")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("hello")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(parens).end_of_input()
+ assert embedded("v=" + "(hello)")
+ assert not embedded("(hello)")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = parens.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/percent.test.py b/tests/atoms/percent.test.py
new file mode 100644
index 0000000..40ad6c9
--- /dev/null
+++ b/tests/atoms/percent.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import percent
+
+
+def _anchored():
+ return Pattern().start_of_input().use(percent).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("50%")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("50")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(percent).end_of_input()
+ assert embedded("v=" + "50%")
+ assert not embedded("50%")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = percent.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/port.test.py b/tests/atoms/port.test.py
new file mode 100644
index 0000000..3c3958b
--- /dev/null
+++ b/tests/atoms/port.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import port
+
+
+def _anchored():
+ return Pattern().start_of_input().use(port).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("65535")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("65536")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(port).end_of_input()
+ assert embedded("v=" + "65535")
+ assert not embedded("65535")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = port.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/printable.test.py b/tests/atoms/printable.test.py
new file mode 100644
index 0000000..3e6a9be
--- /dev/null
+++ b/tests/atoms/printable.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import printable
+
+
+def _anchored():
+ return Pattern().start_of_input().use(printable).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("!")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("\x00")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(printable).end_of_input()
+ assert embedded("v=" + "!")
+ assert not embedded("!")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = printable.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/protocol.test.py b/tests/atoms/protocol.test.py
new file mode 100644
index 0000000..9e546e0
--- /dev/null
+++ b/tests/atoms/protocol.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import protocol
+
+
+def _anchored():
+ return Pattern().start_of_input().use(protocol).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("https")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("smtp")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(protocol).end_of_input()
+ assert embedded("v=" + "https")
+ assert not embedded("https")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = protocol.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/quoted.test.py b/tests/atoms/quoted.test.py
new file mode 100644
index 0000000..e0d409a
--- /dev/null
+++ b/tests/atoms/quoted.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import quoted
+
+
+def _anchored():
+ return Pattern().start_of_input().use(quoted).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()('"hello"')
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("hello")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(quoted).end_of_input()
+ assert embedded("v=" + '"hello"')
+ assert not embedded('"hello"')
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = quoted.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/ratio.test.py b/tests/atoms/ratio.test.py
new file mode 100644
index 0000000..c3ad541
--- /dev/null
+++ b/tests/atoms/ratio.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import ratio
+
+
+def _anchored():
+ return Pattern().start_of_input().use(ratio).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("16:9")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("16")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(ratio).end_of_input()
+ assert embedded("v=" + "16:9")
+ assert not embedded("16:9")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = ratio.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/rgbcolor.test.py b/tests/atoms/rgbcolor.test.py
new file mode 100644
index 0000000..1d0cd23
--- /dev/null
+++ b/tests/atoms/rgbcolor.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import rgbcolor
+
+
+def _anchored():
+ return Pattern().start_of_input().use(rgbcolor).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("rgb(255, 0, 0)")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("nope")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(rgbcolor).end_of_input()
+ assert embedded("v=" + "rgb(255, 0, 0)")
+ assert not embedded("rgb(255, 0, 0)")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = rgbcolor.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/scheme.test.py b/tests/atoms/scheme.test.py
new file mode 100644
index 0000000..1b77a63
--- /dev/null
+++ b/tests/atoms/scheme.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import scheme
+
+
+def _anchored():
+ return Pattern().start_of_input().use(scheme).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("https")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1abc")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(scheme).end_of_input()
+ assert embedded("v=" + "https")
+ assert not embedded("https")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = scheme.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/scientific.test.py b/tests/atoms/scientific.test.py
new file mode 100644
index 0000000..6ccabc4
--- /dev/null
+++ b/tests/atoms/scientific.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import scientific
+
+
+def _anchored():
+ return Pattern().start_of_input().use(scientific).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("1e10")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1.5")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(scientific).end_of_input()
+ assert embedded("v=" + "1e10")
+ assert not embedded("1e10")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = scientific.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/semver.test.py b/tests/atoms/semver.test.py
new file mode 100644
index 0000000..2b173e2
--- /dev/null
+++ b/tests/atoms/semver.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import semver
+
+
+def _anchored():
+ return Pattern().start_of_input().use(semver).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("1.0.0")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("1.0")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(semver).end_of_input()
+ assert embedded("v=" + "1.0.0")
+ assert not embedded("1.0.0")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = semver.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/sha256.test.py b/tests/atoms/sha256.test.py
new file mode 100644
index 0000000..790f62f
--- /dev/null
+++ b/tests/atoms/sha256.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import sha256
+
+
+def _anchored():
+ return Pattern().start_of_input().use(sha256).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("short")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(sha256).end_of_input()
+ assert embedded("v=" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+ assert not embedded("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = sha256.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/signed.test.py b/tests/atoms/signed.test.py
new file mode 100644
index 0000000..ee4521c
--- /dev/null
+++ b/tests/atoms/signed.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import signed
+
+
+def _anchored():
+ return Pattern().start_of_input().use(signed).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("+42")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("42")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(signed).end_of_input()
+ assert embedded("v=" + "+42")
+ assert not embedded("+42")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = signed.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/slug.test.py b/tests/atoms/slug.test.py
new file mode 100644
index 0000000..063e478
--- /dev/null
+++ b/tests/atoms/slug.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import slug
+
+
+def _anchored():
+ return Pattern().start_of_input().use(slug).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("my-slug")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("-bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(slug).end_of_input()
+ assert embedded("v=" + "my-slug")
+ assert not embedded("my-slug")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = slug.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/space.test.py b/tests/atoms/space.test.py
new file mode 100644
index 0000000..1651bb9
--- /dev/null
+++ b/tests/atoms/space.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import space
+
+
+def _anchored():
+ return Pattern().start_of_input().use(space).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()(" ")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("a")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(space).end_of_input()
+ assert embedded("v=" + " ")
+ assert not embedded(" ")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = space.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/timezone.test.py b/tests/atoms/timezone.test.py
new file mode 100644
index 0000000..d1d4992
--- /dev/null
+++ b/tests/atoms/timezone.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import timezone
+
+
+def _anchored():
+ return Pattern().start_of_input().use(timezone).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("+05:30")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("bad")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(timezone).end_of_input()
+ assert embedded("v=" + "+05:30")
+ assert not embedded("+05:30")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = timezone.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/tld.test.py b/tests/atoms/tld.test.py
new file mode 100644
index 0000000..f61c4a8
--- /dev/null
+++ b/tests/atoms/tld.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import tld
+
+
+def _anchored():
+ return Pattern().start_of_input().use(tld).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("com")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("a")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(tld).end_of_input()
+ assert embedded("v=" + "com")
+ assert not embedded("com")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = tld.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/truefalse.test.py b/tests/atoms/truefalse.test.py
new file mode 100644
index 0000000..817bd3d
--- /dev/null
+++ b/tests/atoms/truefalse.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import truefalse
+
+
+def _anchored():
+ return Pattern().start_of_input().use(truefalse).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("true")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("maybe")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(truefalse).end_of_input()
+ assert embedded("v=" + "true")
+ assert not embedded("true")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = truefalse.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/ulid.test.py b/tests/atoms/ulid.test.py
new file mode 100644
index 0000000..94ce256
--- /dev/null
+++ b/tests/atoms/ulid.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import ulid
+
+
+def _anchored():
+ return Pattern().start_of_input().use(ulid).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("01ARZ3NDEKTSV4RRFFQ69G5FAV")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("short")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(ulid).end_of_input()
+ assert embedded("v=" + "01ARZ3NDEKTSV4RRFFQ69G5FAV")
+ assert not embedded("01ARZ3NDEKTSV4RRFFQ69G5FAV")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = ulid.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/unsigned.test.py b/tests/atoms/unsigned.test.py
new file mode 100644
index 0000000..28ba4a1
--- /dev/null
+++ b/tests/atoms/unsigned.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import unsigned
+
+
+def _anchored():
+ return Pattern().start_of_input().use(unsigned).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("42")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("-42")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(unsigned).end_of_input()
+ assert embedded("v=" + "42")
+ assert not embedded("42")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = unsigned.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/upper.test.py b/tests/atoms/upper.test.py
new file mode 100644
index 0000000..2817c0c
--- /dev/null
+++ b/tests/atoms/upper.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import upper
+
+
+def _anchored():
+ return Pattern().start_of_input().use(upper).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("A")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("a")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(upper).end_of_input()
+ assert embedded("v=" + "A")
+ assert not embedded("A")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = upper.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/uri.test.py b/tests/atoms/uri.test.py
new file mode 100644
index 0000000..5034d04
--- /dev/null
+++ b/tests/atoms/uri.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import uri
+
+
+def _anchored():
+ return Pattern().start_of_input().use(uri).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("mailto:[email protected]")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("just")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(uri).end_of_input()
+ assert embedded("v=" + "mailto:[email protected]")
+ assert not embedded("mailto:[email protected]")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = uri.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/url.test.py b/tests/atoms/url.test.py
new file mode 100644
index 0000000..73d52a9
--- /dev/null
+++ b/tests/atoms/url.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import url
+
+
+def _anchored():
+ return Pattern().start_of_input().use(url).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("https://example.com")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("not a url")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(url).end_of_input()
+ assert embedded("v=" + "https://example.com")
+ assert not embedded("https://example.com")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = url.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/username.test.py b/tests/atoms/username.test.py
new file mode 100644
index 0000000..392bb70
--- /dev/null
+++ b/tests/atoms/username.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import username
+
+
+def _anchored():
+ return Pattern().start_of_input().use(username).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("bob")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("ab")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(username).end_of_input()
+ assert embedded("v=" + "bob")
+ assert not embedded("bob")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = username.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/uuid.test.py b/tests/atoms/uuid.test.py
new file mode 100644
index 0000000..b085719
--- /dev/null
+++ b/tests/atoms/uuid.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import uuid
+
+
+def _anchored():
+ return Pattern().start_of_input().use(uuid).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("550e8400-e29b-41d4-a716-446655440000")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("nope")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(uuid).end_of_input()
+ assert embedded("v=" + "550e8400-e29b-41d4-a716-446655440000")
+ assert not embedded("550e8400-e29b-41d4-a716-446655440000")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = uuid.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/weekday.test.py b/tests/atoms/weekday.test.py
new file mode 100644
index 0000000..c6f240e
--- /dev/null
+++ b/tests/atoms/weekday.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import weekday
+
+
+def _anchored():
+ return Pattern().start_of_input().use(weekday).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("Mon")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("Xyz")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(weekday).end_of_input()
+ assert embedded("v=" + "Mon")
+ assert not embedded("Mon")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = weekday.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/word.test.py b/tests/atoms/word.test.py
new file mode 100644
index 0000000..c73086e
--- /dev/null
+++ b/tests/atoms/word.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import word
+
+
+def _anchored():
+ return Pattern().start_of_input().use(word).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("hello_1")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("has space")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(word).end_of_input()
+ assert embedded("v=" + "hello_1")
+ assert not embedded("hello_1")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = word.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/year.test.py b/tests/atoms/year.test.py
new file mode 100644
index 0000000..cb34916
--- /dev/null
+++ b/tests/atoms/year.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import year
+
+
+def _anchored():
+ return Pattern().start_of_input().use(year).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("2024")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("24")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(year).end_of_input()
+ assert embedded("v=" + "2024")
+ assert not embedded("2024")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = year.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)
diff --git a/tests/atoms/yesno.test.py b/tests/atoms/yesno.test.py
new file mode 100644
index 0000000..775c1bb
--- /dev/null
+++ b/tests/atoms/yesno.test.py
@@ -0,0 +1,26 @@
+from edify import Pattern
+from edify.atoms import yesno
+
+
+def _anchored():
+ return Pattern().start_of_input().use(yesno).end_of_input()
+
+
+def test_accepts_sample_from_shape():
+ assert _anchored()("yes")
+
+
+def test_rejects_off_shape_input():
+ assert not _anchored()("maybe")
+
+
+def test_atom_composes_inside_a_larger_pattern():
+ embedded = Pattern().start_of_input().string("v=").use(yesno).end_of_input()
+ assert embedded("v=" + "yes")
+ assert not embedded("yes")
+
+
+def test_atom_regex_string_is_non_empty():
+ fragment = yesno.to_regex_string()
+ assert fragment
+ assert isinstance(fragment, str)