summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2020-06-26 21:00:36 -0400
committerGitHub <noreply@github.com>2020-06-26 21:00:36 -0400
commitffdee71864aad8f9f3c4338c3dd056467528550f (patch)
treebe5b80ee3299b6167b21ff191de97badf2826208
parent0c07f57ba54cfc06b6411846c017bc79cee4a33a (diff)
parent2f4c89cd3133517f58bc9e42f29220a1bbb66bcc (diff)
Merge pull request #12 from ojacobson/proptest
Switch from quickcheck to proptest.
-rw-r--r--Cargo.lock239
-rw-r--r--Cargo.toml4
-rw-r--r--proptest-regressions/twelve.txt9
-rw-r--r--src/twelve.rs127
4 files changed, 242 insertions, 137 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cee3a90..f14b40c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -87,8 +87,8 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a60f9ba7c4e6df97f3aacb14bb5c0cd7d98a49dcbaed0d7f292912ad9a6a3ed2"
dependencies = [
- "quote",
- "syn",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -252,9 +252,9 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a71bf475cbe07281d0b3696abb48212db118e7e23219f13596ce865235ff5766"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -293,9 +293,9 @@ version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -347,6 +347,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]]
+name = "bit-set"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
+dependencies = [
+ "bit-vec",
+]
+
+[[package]]
+name = "bit-vec"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f0dc55f2d8a1a85650ac47858bb001b4c0dd73d79e3c455a842925e68d29cd3"
+
+[[package]]
name = "bitflags"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -446,9 +461,9 @@ version = "0.99.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2127768764f1556535c01b5326ef94bd60ff08dcfbdc544d53e69ed155610f5d"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -479,19 +494,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc4bfcfacb61d231109d1d55202c1f33263319668b168843e02ad4652725ec9c"
dependencies = [
"heck",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "env_logger"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
-dependencies = [
- "log",
- "regex",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -510,9 +515,9 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
"synstructure",
]
@@ -605,9 +610,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
dependencies = [
"proc-macro-hack",
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -888,7 +893,7 @@ source = "git+https://github.com/lambda-fairy/maud#240ecf03b8c16021a609397a056d6
dependencies = [
"matches",
"maud_htmlescape",
- "syn",
+ "syn 1.0.30",
]
[[package]]
@@ -1051,9 +1056,9 @@ version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e58db2081ba5b4c93bd6be09c40fd36cb9193a8336c384f3b40012e531aa7e40"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -1088,11 +1093,51 @@ checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
[[package]]
name = "proc-macro2"
+version = "0.4.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
+dependencies = [
+ "unicode-xid 0.1.0",
+]
+
+[[package]]
+name = "proc-macro2"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
dependencies = [
- "unicode-xid",
+ "unicode-xid 0.2.0",
+]
+
+[[package]]
+name = "proptest"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2520fe6373cf6a3a61e2d200e987c183778ade8d9248ac3e6614ab0edfe4a0c1"
+dependencies = [
+ "bit-set",
+ "bitflags",
+ "byteorder",
+ "lazy_static",
+ "num-traits",
+ "quick-error",
+ "rand",
+ "rand_chacha",
+ "rand_xorshift",
+ "regex-syntax",
+ "rusty-fork",
+ "tempfile",
+]
+
+[[package]]
+name = "proptest-derive"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "051d9d20dbe9e9dfe594328b6eaab72ccf571fee818991dd1c1ba5469b5f32d4"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "syn 0.15.44",
]
[[package]]
@@ -1114,26 +1159,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
-name = "quickcheck"
-version = "0.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f"
-dependencies = [
- "env_logger",
- "log",
- "rand",
- "rand_core",
-]
-
-[[package]]
-name = "quickcheck_macros"
-version = "0.9.1"
+name = "quote"
+version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "608c156fd8e97febc07dc9c2e2c80bf74cfc6ef26893eae3daf8bc2bc94a4b7f"
+checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 0.4.30",
]
[[package]]
@@ -1142,7 +1173,7 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea"
dependencies = [
- "proc-macro2",
+ "proc-macro2 1.0.18",
]
[[package]]
@@ -1187,6 +1218,15 @@ dependencies = [
]
[[package]]
+name = "rand_xorshift"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
+dependencies = [
+ "rand_core",
+]
+
+[[package]]
name = "redox_syscall"
version = "0.1.56"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1211,6 +1251,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26412eb97c6b088a6997e05f69403a802a92d520de2f8e63c2b65f9e0f47c4e8"
[[package]]
+name = "remove_dir_all"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
+dependencies = [
+ "winapi 0.3.8",
+]
+
+[[package]]
name = "resolv-conf"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1227,6 +1276,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]]
+name = "rusty-fork"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
+dependencies = [
+ "fnv",
+ "quick-error",
+ "tempfile",
+ "wait-timeout",
+]
+
+[[package]]
name = "ryu"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1253,9 +1314,9 @@ version = "1.0.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f2c3ac8e6ca1e9c80b8be1023940162bf81ae3cffbb1809474152f2ce1eb250"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -1335,13 +1396,24 @@ dependencies = [
[[package]]
name = "syn"
+version = "0.15.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
+dependencies = [
+ "proc-macro2 0.4.30",
+ "quote 0.6.13",
+ "unicode-xid 0.1.0",
+]
+
+[[package]]
+name = "syn"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93a56fabc59dce20fe48b6c832cc249c713e7ed88fa28b0ee0a3bfcaae5fe4e2"
dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "unicode-xid 0.2.0",
]
[[package]]
@@ -1350,10 +1422,24 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
- "unicode-xid",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
+ "unicode-xid 0.2.0",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "rand",
+ "redox_syscall",
+ "remove_dir_all",
+ "winapi 0.3.8",
]
[[package]]
@@ -1364,9 +1450,9 @@ dependencies = [
"actix-web",
"lazy_static",
"maud",
+ "proptest",
+ "proptest-derive",
"pulldown-cmark",
- "quickcheck",
- "quickcheck_macros",
"rand",
"serde",
"serde_urlencoded",
@@ -1390,9 +1476,9 @@ version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "893582086c2f98cde18f906265a65b5030a074b1046c674ae898be6519a7f479"
dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "proc-macro2 1.0.18",
+ "quote 1.0.6",
+ "syn 1.0.30",
]
[[package]]
@@ -1551,6 +1637,12 @@ checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479"
[[package]]
name = "unicode-xid"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
+
+[[package]]
+name = "unicode-xid"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
@@ -1573,6 +1665,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
+name = "wait-timeout"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index d08aaee..b4ca8a7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,5 +28,5 @@ features = ["actix-web"]
[dev-dependencies]
lazy_static = "~1.4"
-quickcheck = "~0.9"
-quickcheck_macros = "~0.9"
+proptest = "~0.10"
+proptest-derive = "~0.2"
diff --git a/proptest-regressions/twelve.txt b/proptest-regressions/twelve.txt
new file mode 100644
index 0000000..320b1b0
--- /dev/null
+++ b/proptest-regressions/twelve.txt
@@ -0,0 +1,9 @@
+# Seeds for failure cases proptest has generated in the past. It is
+# automatically read and these particular cases re-run before any
+# novel cases are generated.
+#
+# It is recommended to check this file in to source control so that
+# everyone who runs the test benefits from these saved cases.
+cc ee722004cd7dc5c8cfa8af5d83428a3c76f247525f738520e197ed67a0679b17 # shrinks to env_port = "", default_port = 0
+cc 8a8acaaebfe4e37af7655f14c3d9a394b2b3cc700936e36348158018ae8795ea # shrinks to env_port = "𐠁{�\"Tz`ﰃQ𑴉:*꠶䌁.", default_port = 42943
+cc f4d12f4f852ebcc99f6aa1a5208a392414d31dd98f025a7a905e1ef800d963af # shrinks to default_port = 65
diff --git a/src/twelve.rs b/src/twelve.rs
index 273b17f..7803450 100644
--- a/src/twelve.rs
+++ b/src/twelve.rs
@@ -8,6 +8,8 @@
//! [1]: https://12factor.net/
//! [2]: https://12factor.net/config
+#[cfg(test)]
+use proptest_derive::Arbitrary;
use std::env;
use std::io;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
@@ -47,6 +49,7 @@ pub enum Error {
/// Listening on this address will bind to both the ip4 and ip6 addresses on the
/// current host, assuming both ip4 and ip6 are supported.
#[derive(Debug, Clone)]
+#[cfg_attr(test, derive(Arbitrary))]
pub struct PortAddr {
/// When used in an std::net::SocketAddr context, this is the port number to
/// bind on.
@@ -104,8 +107,7 @@ pub fn port(default_port: u16) -> Result<PortAddr, Error> {
#[cfg(test)]
mod tests {
use lazy_static::lazy_static;
- use quickcheck::{Arbitrary, Gen, TestResult};
- use quickcheck_macros::quickcheck;
+ use proptest::prelude::*;
use std::env;
use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
@@ -113,39 +115,33 @@ mod tests {
use super::*;
- impl Arbitrary for PortAddr {
- fn arbitrary<G: Gen>(g: &mut G) -> Self {
- Self {
- port: u16::arbitrary(g),
- }
- }
- }
-
- #[quickcheck]
- fn port_addr_as_socket_addr_has_v4(addr: PortAddr) -> bool {
- let socket_addrs = addr.to_socket_addrs().unwrap().collect::<Vec<_>>();
+ proptest! {
+ #[test]
+ fn port_addr_as_socket_addr_has_v4(addr: PortAddr) {
+ let socket_addrs: Vec<_> = addr.to_socket_addrs().unwrap().collect();
- socket_addrs
- .iter()
- .any(|&socket_addr| socket_addr.is_ipv4())
- }
+ assert!(socket_addrs
+ .iter()
+ .any(|&socket_addr| socket_addr.is_ipv4()));
+ }
- #[quickcheck]
- fn port_addr_as_socket_addr_has_v6(addr: PortAddr) -> bool {
- let socket_addrs = addr.to_socket_addrs().unwrap().collect::<Vec<_>>();
+ #[test]
+ fn port_addr_as_socket_addr_has_v6(addr: PortAddr) {
+ let socket_addrs: Vec<_> = addr.to_socket_addrs().unwrap().collect();
- socket_addrs
- .iter()
- .any(|&socket_addr| socket_addr.is_ipv6())
- }
+ assert!(socket_addrs
+ .iter()
+ .any(|&socket_addr| socket_addr.is_ipv6()));
+ }
- #[quickcheck]
- fn port_addr_as_socket_addr_all_have_port(addr: PortAddr) -> bool {
- let socket_addrs = addr.to_socket_addrs().unwrap().collect::<Vec<_>>();
+ #[test]
+ fn port_addr_as_socket_addr_all_have_port(addr: PortAddr) {
+ let socket_addrs: Vec<_> = addr.to_socket_addrs().unwrap().collect();
- socket_addrs
- .iter()
- .all(|&socket_addr| socket_addr.port() == addr.port)
+ assert!(socket_addrs
+ .iter()
+ .all(|&socket_addr| socket_addr.port() == addr.port));
+ }
}
#[derive(Default)]
@@ -161,10 +157,10 @@ mod tests {
lazy_static! {
// The tests in this module manipulate a global, shared, external
- // resource (the PORT environment variable). The quickcheck tool
- // attempts to accelerate testing by running multiple threads, but this
- // causes race conditions as test A stomps on state used by test B.
- // Serialize tests through a mutex.
+ // resource (the PORT environment variable). The proptest tool attempts
+ // to accelerate testing by running multiple threads, but this causes
+ // race conditions as test A stomps on state used by test B. Serialize
+ // tests through a mutex.
//
// Huge hack.
static ref ENV_MUTEX: Mutex<Runner> = Mutex::new(Runner::default());
@@ -175,48 +171,47 @@ mod tests {
ENV_MUTEX.lock().unwrap().run(f)
}
- #[quickcheck]
- fn port_preserves_numeric_values(env_port: u16, default_port: u16) -> TestResult {
- if env_port == default_port {
- return TestResult::discard();
- }
+ proptest! {
+ #[test]
+ fn port_preserves_numeric_values(env_port: u16, default_port: u16) {
+ prop_assume!(env_port != default_port);
- env_locked(|| {
- env::set_var("PORT", env_port.to_string());
+ env_locked(|| {
+ env::set_var("PORT", env_port.to_string());
- let read_port = port(default_port).unwrap();
+ let read_port = port(default_port).unwrap();
- TestResult::from_bool(read_port.port == env_port)
- })
- }
-
- #[quickcheck]
- fn port_rejects_strings(env_port: String, default_port: u16) -> TestResult {
- if env_port.contains("\x00") {
- return TestResult::discard();
- }
- if env_port.parse::<u16>().is_ok() {
- return TestResult::discard();
+ assert_eq!(read_port.port, env_port);
+ });
}
- env_locked(|| {
- env::set_var("PORT", env_port.to_string());
+ #[test]
+ fn port_rejects_strings(env_port: String, default_port: u16) {
+ // Reject any sample with a NUL byte; env::set_var (well, libc)
+ // can't cope.
+ prop_assume!(!env_port.contains("\x00"));
+ // Reject any sample that _should_ parse cleanly.
+ prop_assume!(env_port.parse::<u16>().is_err());
- let port_result = port(default_port);
+ env_locked(|| {
+ env::set_var("PORT", env_port.to_string());
- TestResult::from_bool(port_result.is_err())
- })
- }
+ let port_result = port(default_port);
- #[quickcheck]
- fn port_uses_default(default_port: u16) -> bool {
- env_locked(|| {
- env::remove_var("PORT");
+ assert!(port_result.is_err());
+ });
+ }
- let read_port = port(default_port).unwrap();
+ #[test]
+ fn port_uses_default(default_port: u16) {
+ env_locked(|| {
+ env::remove_var("PORT");
- read_port.port == default_port
- })
+ let read_port = port(default_port).unwrap();
+
+ assert_eq!(default_port, read_port.port);
+ });
+ }
}
#[test]