Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  wpt.rs   Sprache: unbekannt

 
// Copyright 2013-2014 The rust-url developers.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Data-driven tests imported from web-platform-tests

use serde_json::Value;
use std::collections::HashMap;
use std::fmt::Write;
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use std::sync::Mutex;
use url::Url;

// https://rustwasm.github.io/wasm-bindgen/wasm-bindgen-test/usage.html
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use wasm_bindgen_test::{console_log, wasm_bindgen_test, wasm_bindgen_test_configure};
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
wasm_bindgen_test_configure!(run_in_browser);

// wpt has its own test driver, but we shoe-horn this into wasm_bindgen_test
// which will discard stdout and stderr. So, we make println! go to
// console.log(), so we see failures that do not result in panics.

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
static PRINT_BUF: Mutex<Option<String>> = Mutex::new(None);

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
macro_rules! print {
    ($($arg:tt)*) => {
        let v = format!($($arg)*);
        {
            let mut buf = PRINT_BUF.lock().unwrap();
            if let Some(buf) = buf.as_mut() {
                buf.push_str(&v);
            } else {
                *buf = Some(v);
            }
        }
    };
}

#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
macro_rules! println {
    () => {
        let buf = PRINT_BUF.lock().unwrap().take();
        match buf {
            Some(buf) => console_log!("{buf}"),
            None => console_log!(""),
        }
    };
    ($($arg:tt)*) => {
        let buf = PRINT_BUF.lock().unwrap().take();
        match buf {
            Some(buf) => {
                let v = format!($($arg)*);
                console_log!("{buf}{v}");
            },
            None => console_log!($($arg)*),
        }
    }
}

#[derive(Debug, serde::Deserialize)]
struct UrlTest {
    input: String,
    base: Option<String>,
    #[serde(flatten)]
    result: UrlTestResult,
}

#[derive(Debug, serde::Deserialize)]
#[serde(untagged)]
#[allow(clippy::large_enum_variant)]
enum UrlTestResult {
    Ok(UrlTestOk),
    Fail(UrlTestFail),
}

#[derive(Debug, serde::Deserialize)]
struct UrlTestOk {
    href: String,
    protocol: String,
    username: String,
    password: String,
    host: String,
    hostname: String,
    port: String,
    pathname: String,
    search: String,
    hash: String,
}

#[derive(Debug, serde::Deserialize)]
struct UrlTestFail {
    failure: bool,
}

#[derive(Debug, serde::Deserialize)]
struct SetterTest {
    href: String,
    new_value: String,
    expected: SetterTestExpected,
}

#[derive(Debug, serde::Deserialize)]
struct SetterTestExpected {
    href: Option<String>,
    protocol: Option<String>,
    username: Option<String>,
    password: Option<String>,
    host: Option<String>,
    hostname: Option<String>,
    port: Option<String>,
    pathname: Option<String>,
    search: Option<String>,
    hash: Option<String>,
}

#[cfg_attr(all(target_arch = "wasm32", target_os = "unknown"), wasm_bindgen_test)]
fn main() {
    let mut filter = None;
    let mut args = std::env::args().skip(1);
    while filter.is_none() {
        if let Some(arg) = args.next() {
            if arg == "--test-threads" {
                args.next();
                continue;
            }
            filter = Some(arg);
        } else {
            break;
        }
    }

    let mut expected_failures = include_str!("expected_failures.txt")
        .lines()
        .collect::<Vec<_>>();

    let mut errors = vec![];

    // Copied from https://github.com/web-platform-tests/wpt/blob/master/url/
    let url_json: Vec<Value> = serde_json::from_str(include_str!("urltestdata.json"))
        .expect("JSON parse error in urltestdata.json");
    let url_tests = url_json
        .into_iter()
        .filter(|val| val.is_object())
        .map(|val| serde_json::from_value::<UrlTest>(val).expect("parsing failed"))
        .collect::<Vec<_>>();

    let setter_json: HashMap<String, Value> =
        serde_json::from_str(include_str!("setters_tests.json"))
            .expect("JSON parse error in setters_tests.json");
    let setter_tests = setter_json
        .into_iter()
        .filter(|(k, _)| k != "comment")
        .map(|(k, v)| {
            let test = serde_json::from_value::<Vec<SetterTest>>(v).expect("parsing failed");
            (k, test)
        })
        .collect::<HashMap<_, _>>();

    for url_test in url_tests {
        let mut name = format!("<{}>", url_test.input.escape_default());
        if let Some(base) = &url_test.base {
            write!(&mut name, " against <{}>", base.escape_default()).unwrap();
        }
        if should_skip(&name, filter.as_deref()) {
            continue;
        }
        print!("{} ... ", name);

        let res = run_url_test(url_test);
        report(name, res, &mut errors, &mut expected_failures);
    }

    for (kind, tests) in setter_tests {
        for test in tests {
            let name = format!(
                "<{}> set {} to <{}>",
                test.href.escape_default(),
                kind,
                test.new_value.escape_default()
            );
            if should_skip(&name, filter.as_deref()) {
                continue;
            }

            print!("{} ... ", name);

            let res = run_setter_test(&kind, test);
            report(name, res, &mut errors, &mut expected_failures);
        }
    }

    println!();
    println!("====================");
    println!();

    if !errors.is_empty() {
        println!("errors:");
        println!();

        for (name, err) in errors {
            println!("  name: {}", name);
            println!("  err:  {}", err);
            println!();
        }

        std::process::exit(1);
    } else {
        println!("all tests passed");
    }

    if !expected_failures.is_empty() && filter.is_none() {
        println!();
        println!("====================");
        println!();
        println!("tests were expected to fail but did not run:");
        println!();

        for name in expected_failures {
            println!("  {}", name);
        }

        println!();
        println!("if these tests were removed, update expected_failures.txt");
        println!();

        std::process::exit(1);
    }
}

fn should_skip(name: &str, filter: Option<&str>) -> bool {
    match filter {
        Some(filter) => !name.contains(filter),
        None => false,
    }
}

fn report(
    name: String,
    res: Result<(), String>,
    errors: &mut Vec<(String, String)>,
    expected_failures: &mut Vec<&str>,
) {
    let expected_failure = expected_failures.contains(&&*name);
    expected_failures.retain(|&s| s != &*name);
    match res {
        Ok(()) => {
            if expected_failure {
                println!("�� (unexpected success)");
                errors.push((name, "unexpected success".to_string()));
            } else {
                println!("✅");
            }
        }
        Err(err) => {
            if expected_failure {
                println!("✅ (expected fail)");
            } else {
                println!("❌");
                errors.push((name, err));
            }
        }
    }
}

fn run_url_test(
    UrlTest {
        base,
        input,
        result,
    }: UrlTest,
) -> Result<(), String> {
    let base = match base {
        Some(base) => {
            let base =
                Url::parse(&base).map_err(|e| format!("errored while parsing base: {}", e))?;
            Some(base)
        }
        None => None,
    };

    let res = Url::options()
        .base_url(base.as_ref())
        .parse(&input)
        .map_err(|e| format!("errored while parsing input: {}", e));

    match result {
        UrlTestResult::Ok(ok) => check_url_ok(res, ok),
        UrlTestResult::Fail(fail) => {
            assert!(fail.failure);
            if res.is_ok() {
                return Err("expected failure, but parsed successfully".to_string());
            }

            Ok(())
        }
    }
}

fn check_url_ok(res: Result<Url, String>, ok: UrlTestOk) -> Result<(), String> {
    let url = match res {
        Ok(url) => url,
        Err(err) => {
            return Err(format!("expected success, but errored: {:?}", err));
        }
    };

    let href = url::quirks::href(&url);
    if href != ok.href {
        return Err(format!("expected href {:?}, but got {:?}", ok.href, href));
    }

    let protocol = url::quirks::protocol(&url);
    if protocol != ok.protocol {
        return Err(format!(
            "expected protocol {:?}, but got {:?}",
            ok.protocol, protocol
        ));
    }

    let username = url::quirks::username(&url);
    if username != ok.username {
        return Err(format!(
            "expected username {:?}, but got {:?}",
            ok.username, username
        ));
    }

    let password = url::quirks::password(&url);
    if password != ok.password {
        return Err(format!(
            "expected password {:?}, but got {:?}",
            ok.password, password
        ));
    }

    let host = url::quirks::host(&url);
    if host != ok.host {
        return Err(format!("expected host {:?}, but got {:?}", ok.host, host));
    }

    let hostname = url::quirks::hostname(&url);
    if hostname != ok.hostname {
        return Err(format!(
            "expected hostname {:?}, but got {:?}",
            ok.hostname, hostname
        ));
    }

    let port = url::quirks::port(&url);
    if port != ok.port {
        return Err(format!("expected port {:?}, but got {:?}", ok.port, port));
    }

    let pathname = url::quirks::pathname(&url);
    if pathname != ok.pathname {
        return Err(format!(
            "expected pathname {:?}, but got {:?}",
            ok.pathname, pathname
        ));
    }

    let search = url::quirks::search(&url);
    if search != ok.search {
        return Err(format!(
            "expected search {:?}, but got {:?}",
            ok.search, search
        ));
    }

    let hash = url::quirks::hash(&url);
    if hash != ok.hash {
        return Err(format!("expected hash {:?}, but got {:?}", ok.hash, hash));
    }

    Ok(())
}

fn run_setter_test(
    kind: &str,
    SetterTest {
        href,
        new_value,
        expected,
    }: SetterTest,
) -> Result<(), String> {
    let mut url = Url::parse(&href).map_err(|e| format!("errored while parsing href: {}", e))?;

    match kind {
        "protocol" => {
            url::quirks::set_protocol(&mut url, &new_value).ok();
        }
        "username" => {
            url::quirks::set_username(&mut url, &new_value).ok();
        }
        "password" => {
            url::quirks::set_password(&mut url, &new_value).ok();
        }
        "host" => {
            url::quirks::set_host(&mut url, &new_value).ok();
        }
        "hostname" => {
            url::quirks::set_hostname(&mut url, &new_value).ok();
        }
        "port" => {
            url::quirks::set_port(&mut url, &new_value).ok();
        }
        "pathname" => url::quirks::set_pathname(&mut url, &new_value),
        "search" => url::quirks::set_search(&mut url, &new_value),
        "hash" => url::quirks::set_hash(&mut url, &new_value),
        _ => {
            return Err(format!("unknown setter kind: {:?}", kind));
        }
    }

    if let Some(expected_href) = expected.href {
        let href = url::quirks::href(&url);
        if href != expected_href {
            return Err(format!(
                "expected href {:?}, but got {:?}",
                expected_href, href
            ));
        }
    }

    if let Some(expected_protocol) = expected.protocol {
        let protocol = url::quirks::protocol(&url);
        if protocol != expected_protocol {
            return Err(format!(
                "expected protocol {:?}, but got {:?}",
                expected_protocol, protocol
            ));
        }
    }

    if let Some(expected_username) = expected.username {
        let username = url::quirks::username(&url);
        if username != expected_username {
            return Err(format!(
                "expected username {:?}, but got {:?}",
                expected_username, username
            ));
        }
    }

    if let Some(expected_password) = expected.password {
        let password = url::quirks::password(&url);
        if password != expected_password {
            return Err(format!(
                "expected password {:?}, but got {:?}",
                expected_password, password
            ));
        }
    }

    if let Some(expected_host) = expected.host {
        let host = url::quirks::host(&url);
        if host != expected_host {
            return Err(format!(
                "expected host {:?}, but got {:?}",
                expected_host, host
            ));
        }
    }

    if let Some(expected_hostname) = expected.hostname {
        let hostname = url::quirks::hostname(&url);
        if hostname != expected_hostname {
            return Err(format!(
                "expected hostname {:?}, but got {:?}",
                expected_hostname, hostname
            ));
        }
    }

    if let Some(expected_port) = expected.port {
        let port = url::quirks::port(&url);
        if port != expected_port {
            return Err(format!(
                "expected port {:?}, but got {:?}",
                expected_port, port
            ));
        }
    }

    if let Some(expected_pathname) = expected.pathname {
        let pathname = url::quirks::pathname(&url);
        if pathname != expected_pathname {
            return Err(format!(
                "expected pathname {:?}, but got {:?}",
                expected_pathname, pathname
            ));
        }
    }

    if let Some(expected_search) = expected.search {
        let search = url::quirks::search(&url);
        if search != expected_search {
            return Err(format!(
                "expected search {:?}, but got {:?}",
                expected_search, search
            ));
        }
    }

    if let Some(expected_hash) = expected.hash {
        let hash = url::quirks::hash(&url);
        if hash != expected_hash {
            return Err(format!(
                "expected hash {:?}, but got {:?}",
                expected_hash, hash
            ));
        }
    }

    Ok(())
}

[ Dauer der Verarbeitung: 0.29 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge