aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates/shirabe/tests/common/http_downloader_mock.rs
blob: 85d3ec81e0add285d25efc835a6e8b03352c234c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! ref: composer/tests/Composer/Test/Mock/HttpDownloaderMock.php
#![allow(dead_code)]

use indexmap::IndexMap;
use shirabe::config::Config;
use shirabe::io::IOInterface;
use shirabe::io::null_io::NullIO;
use shirabe::util::http_downloader::{
    HttpDownloader, HttpDownloaderMockExpectation, HttpDownloaderMockHandler,
};
use shirabe_php_shim::PhpMixed;
use std::cell::RefCell;
use std::rc::Rc;

// A single HTTP request expectation as written in the PHP tests: a `url` plus an
// optional response (`status`/`body`/`headers`). `options` of `None` matches any
// options; `Some(..)` requires an exact match against the executed options.
pub fn expect(url: impl Into<String>) -> HttpDownloaderMockExpectation {
    HttpDownloaderMockExpectation {
        url: url.into(),
        options: None,
        status: 200,
        body: String::new(),
        headers: vec![String::new()],
    }
}

pub fn expect_full(
    url: impl Into<String>,
    options: Option<IndexMap<String, PhpMixed>>,
    status: i64,
    body: impl Into<String>,
    headers: Vec<String>,
) -> HttpDownloaderMockExpectation {
    HttpDownloaderMockExpectation {
        url: url.into(),
        options,
        status,
        body: body.into(),
        headers,
    }
}

pub struct HttpDownloaderMockGuard(Rc<RefCell<HttpDownloader>>);

impl Drop for HttpDownloaderMockGuard {
    fn drop(&mut self) {
        // Avoid aborting on a double panic when a test assertion is already unwinding.
        if std::thread::panicking() {
            return;
        }
        self.0.borrow().__assert_complete();
    }
}

// For testing only. Mirrors TestCase::getHttpDownloaderMock: returns a shared
// HttpDownloader handle configured with the given expectations, plus a guard that
// runs `__assert_complete` when it drops at the end of the test scope.
pub fn get_http_downloader_mock(
    expectations: Vec<HttpDownloaderMockExpectation>,
    strict: bool,
    default_handler: HttpDownloaderMockHandler,
) -> (Rc<RefCell<HttpDownloader>>, HttpDownloaderMockGuard) {
    let io: Rc<RefCell<dyn IOInterface>> = Rc::new(RefCell::new(NullIO::new()));
    let config = Rc::new(RefCell::new(Config::new(false, None)));
    let downloader = Rc::new(RefCell::new(HttpDownloader::__new_mock(io, config)));
    downloader
        .borrow_mut()
        .__expects(expectations, strict, default_handler);
    (downloader.clone(), HttpDownloaderMockGuard(downloader))
}