http-constant 22.0.7

A comprehensive library providing common HTTP constants for header names, versions, MIME types, and protocol identifiers.
Documentation
use super::*;

#[test]
fn http_methods_are_uppercase_tokens() {
    assert_eq!(GET, "GET");
    assert_eq!(POST, "POST");
    assert_eq!(PUT, "PUT");
    assert_eq!(DELETE, "DELETE");
    assert_eq!(HEAD, "HEAD");
    assert_eq!(OPTIONS, "OPTIONS");
    assert_eq!(PATCH, "PATCH");
}

#[test]
fn header_keys_are_lowercase_tokens() {
    assert_eq!(CONTENT_TYPE, "content-type");
    assert_eq!(CONTENT_LENGTH, "content-length");
    assert_eq!(CONTENT_ENCODING, "content-encoding");
    assert_eq!(TRANSFER_ENCODING, "transfer-encoding");
    assert_eq!(ACCEPT_ENCODING, "accept-encoding");
}

#[test]
fn header_keys_contain_no_whitespace() {
    let keys: Vec<&str> = vec![
        CONTENT_TYPE,
        CONTENT_LENGTH,
        CONTENT_ENCODING,
        TRANSFER_ENCODING,
        ACCEPT_ENCODING,
        SERVER,
        HOST,
    ];
    for key in keys {
        assert!(!key.contains(' '), "header key has a space: {key}");
        assert!(!key.contains('\t'), "header key has a tab: {key}");
        assert_eq!(key, key.to_lowercase());
    }
}

#[test]
fn content_type_values_are_lowercase_media_types() {
    assert_eq!(APPLICATION_JSON, "application/json");
    assert_eq!(TEXT_HTML, "text/html");
    assert_eq!(TEXT_PLAIN, "text/plain");
}

#[test]
fn media_types_are_lowercase_and_slash_separated() {
    let types: Vec<&str> = vec![APPLICATION_JSON, TEXT_HTML, TEXT_PLAIN];
    for media in types {
        assert_eq!(media, media.to_lowercase());
        assert!(media.contains('/'), "media type lacks a slash: {media}");
        let parts: Vec<&str> = media.split('/').collect();
        assert_eq!(parts.len(), 2, "media type malformed: {media}");
    }
}

#[test]
fn byte_views_match_their_string_constants() {
    assert_eq!(SPACE_BYTES, SPACE.as_bytes());
    assert_eq!(TAB_BYTES, TAB.as_bytes());
    assert_eq!(BR_BYTES, BR.as_bytes());
    assert_eq!(DOUBLE_BR_BYTES, DOUBLE_BR.as_bytes());
    assert_eq!(COLON_BYTES, COLON.as_bytes());
    assert_eq!(COLON_SPACE_BYTES, COLON_SPACE.as_bytes());
    assert_eq!(EQUAL_BYTES, EQUAL.as_bytes());
    assert_eq!(AND_BYTES, AND.as_bytes());
    assert_eq!(COMMA_BYTES, COMMA.as_bytes());
    assert_eq!(HASH_BYTES, HASH.as_bytes());
    assert_eq!(SEMICOLON_BYTES, SEMICOLON.as_bytes());
    assert_eq!(QUERY_BYTES, QUERY.as_bytes());
    assert_eq!(POINT_BYTES, POINT.as_bytes());
    assert_eq!(ROOT_PATH_BYTES, ROOT_PATH.as_bytes());
    assert_eq!(HTTP_BR_BYTES, HTTP_BR.as_bytes());
    assert_eq!(HTTP_DOUBLE_BR_BYTES, HTTP_DOUBLE_BR.as_bytes());
    assert_eq!(HYPERLANE_BYTES, HYPERLANE.as_bytes());
    assert_eq!(LOCALHOST_BYTES, LOCALHOST.as_bytes());
    assert_eq!(DEFAULT_HTTP_PATH_BYTES, DEFAULT_HTTP_PATH.as_bytes());
}

#[test]
fn single_byte_views_take_the_first_byte() {
    assert_eq!(SPACE_U8, SPACE_BYTES[0]);
    assert_eq!(TAB_U8, TAB_BYTES[0]);
    assert_eq!(COLON_U8, COLON_BYTES[0]);
    assert_eq!(EQUAL_U8, EQUAL_BYTES[0]);
    assert_eq!(AND_U8, AND_BYTES[0]);
    assert_eq!(COMMA_U8, COMMA_BYTES[0]);
    assert_eq!(HASH_U8, HASH_BYTES[0]);
    assert_eq!(SEMICOLON_U8, SEMICOLON_BYTES[0]);
    assert_eq!(QUERY_U8, QUERY_BYTES[0]);
    assert_eq!(POINT_U8, POINT_BYTES[0]);
    assert_eq!(ZERO_STR_U8, ZERO_STR_BYTES[0]);
}

#[test]
fn delimiter_constants_are_single_ascii_characters() {
    let pairs: Vec<(&str, &str)> = vec![
        (SPACE, " "),
        (TAB, "\t"),
        (COLON, ":"),
        (EQUAL, "="),
        (AND, "&"),
        (COMMA, ","),
        (HASH, "#"),
        (SEMICOLON, ";"),
        (QUERY, "?"),
        (POINT, "."),
    ];
    for (actual, expected) in pairs {
        assert_eq!(actual, expected);
        assert_eq!(actual.len(), 1);
    }
}

#[test]
fn multi_char_delimiters_have_expected_content() {
    assert_eq!(BR, "\n");
    assert_eq!(DOUBLE_BR, "\n\n");
    assert_eq!(HTTP_BR, "\r\n");
    assert_eq!(HTTP_DOUBLE_BR, "\r\n\r\n");
    assert_eq!(COLON_SPACE, ": ");
    assert_eq!(SEMICOLON_SPACE, "; ");
}

#[test]
fn empty_and_zero_constants_agree() {
    assert_eq!(EMPTY_STR, "");
    assert!(EMPTY_STR_BYTES.is_empty());
    assert_eq!(ZERO_STR, "0");
    assert_eq!(ZERO_STR_BYTES, ZERO_STR.as_bytes());
}

#[test]
fn http_version_tokens_are_prefixed() {
    assert_eq!(HTTP_VERSION_1_0, "HTTP/1.0");
    assert_eq!(HTTP_VERSION_1_1, "HTTP/1.1");
    assert_eq!(HTTP_VERSION_2, "HTTP/2");
    for version in [HTTP_VERSION_1_0, HTTP_VERSION_1_1, HTTP_VERSION_2] {
        assert!(version.starts_with("HTTP/"));
    }
}

#[test]
fn default_path_and_root_path_agree() {
    assert_eq!(DEFAULT_HTTP_PATH, "/");
    assert_eq!(ROOT_PATH, "/");
    assert_eq!(DEFAULT_HTTP_PATH_BYTES, ROOT_PATH_BYTES);
}

#[test]
fn security_level_limits_are_ordered() {
    let low_body: usize = DEFAULT_LOW_SECURITY_MAX_BODY_SIZE;
    let high_body: usize = DEFAULT_HIGH_SECURITY_MAX_BODY_SIZE;
    let low_path: usize = DEFAULT_LOW_SECURITY_MAX_PATH_SIZE;
    let high_path: usize = DEFAULT_HIGH_SECURITY_MAX_PATH_SIZE;
    let low_headers: usize = DEFAULT_LOW_SECURITY_MAX_HEADER_COUNT;
    let high_headers: usize = DEFAULT_HIGH_SECURITY_MAX_HEADER_COUNT;
    assert!(low_body >= high_body);
    assert!(low_path >= high_path);
    assert!(low_headers >= high_headers);
    assert!(high_body > 0);
    assert!(high_path > 0);
    assert!(high_headers > 0);
}

#[test]
fn buffer_defaults_are_non_zero() {
    let buffer: usize = DEFAULT_BUFFER_SIZE;
    let request_line: usize = REQUEST_LINE_BUFFER_CAPACITY;
    let header_line: usize = HEADER_LINE_BUFFER_CAPACITY;
    let pooled_count: usize = MAX_POOLED_READ_BUFFERS;
    let pooled_size: usize = MAX_POOLED_READ_BUFFER_SIZE;
    assert!(buffer > 0);
    assert!(request_line > 0);
    assert!(header_line > 0);
    assert!(pooled_count > 0);
    assert!(pooled_size > 0);
}

#[test]
fn redirect_limit_is_bounded() {
    let limit: usize = DEFAULT_MAX_REDIRECT_TIMES;
    assert!(limit > 0);
    assert!(limit <= 10);
}

#[test]
fn hyperlane_name_variants_are_consistent() {
    assert_eq!(HYPERLANE, "hyperlane");
    assert_eq!(HYPERLANE_PASCAL_CASE, "Hyperlane");
    assert_eq!(HYPERLANE_UPPERCASE, "HYPERLANE");
    assert_eq!(
        HYPERLANE_PASCAL_CASE_BYTES,
        HYPERLANE_PASCAL_CASE.as_bytes()
    );
    assert_eq!(HYPERLANE_UPPERCASE_BYTES, HYPERLANE_UPPERCASE.as_bytes());
    assert_eq!(HYPERLANE_BYTES, HYPERLANE.as_bytes());
}

#[test]
fn log_level_names_have_expected_values() {
    assert_eq!(ERROR, "error");
    assert_eq!(WARNING, "warning");
    assert_eq!(INFO, "info");
    assert_eq!(DEBUG, "debug");
    assert_eq!(TRACE, "TRACE");
    assert_eq!(SUCCESS, "success");
    assert_eq!(FAIL, "fail");
}

#[test]
fn log_level_byte_views_match() {
    assert_eq!(WARNING_BYTES, WARNING.as_bytes());
    assert_eq!(SUCCESS_BYTES, SUCCESS.as_bytes());
    assert_eq!(FAIL_BYTES, FAIL.as_bytes());
    assert_eq!(ERROR_BYTES, ERROR.as_bytes());
    assert_eq!(INFO_BYTES, INFO.as_bytes());
    assert_eq!(DEBUG_BYTES, DEBUG.as_bytes());
    assert_eq!(PLAIN_BYTES, PLAIN.as_bytes());
    assert_eq!(BINARY_BYTES, BINARY.as_bytes());
}

#[test]
fn bracket_pairs_are_balanced() {
    assert_eq!(LEFT_BRACKET, "{");
    assert_eq!(RIGHT_BRACKET, "}");
    assert_eq!(LEFT_SQUARE_BRACKET, "[");
    assert_eq!(RIGHT_SQUARE_BRACKET, "]");
    assert_eq!(LEFT_PAREN, "(");
    assert_eq!(RIGHT_PAREN, ")");
    assert_eq!(LEFT_BRACKET_BYTES, LEFT_BRACKET.as_bytes());
    assert_eq!(RIGHT_BRACKET_BYTES, RIGHT_BRACKET.as_bytes());
    assert_eq!(LEFT_PAREN_BYTES, LEFT_PAREN.as_bytes());
    assert_eq!(RIGHT_PAREN_BYTES, RIGHT_PAREN.as_bytes());
    assert_eq!(LEFT_SQUARE_BRACKET_BYTES, LEFT_SQUARE_BRACKET.as_bytes());
    assert_eq!(RIGHT_SQUARE_BRACKET_BYTES, RIGHT_SQUARE_BRACKET.as_bytes());
}

#[test]
fn default_ports_are_standard() {
    assert_eq!(DEFAULT_HTTP_PORT, 80);
    assert_eq!(DEFAULT_HTTPS_PORT, 443);
    assert_eq!(DEFAULT_HTTP_PORT_STR, "80");
    assert_eq!(DEFAULT_HTTPS_PORT_STR, "443");
}

#[test]
fn loopback_addresses_are_local() {
    assert_eq!(LOCALHOST, "localhost");
    assert_eq!(LOOPBACK, "127.0.0.1");
    assert_eq!(DEFAULT_HOST_IPV4_ADDR.to_string(), "0.0.0.0");
    assert_eq!(DEFAULT_IPV4_ADDR.to_string(), "0.0.0.0");
}