mirror of
https://github.com/MalteT/mensa.git
synced 2024-10-22 21:59:17 +02:00
Fix race between tests, add DummyCache
Reworked DummyCache indexing, removed broken top-level tests. Added a simple test deserializing a canteen. Added DummyCache for tests. See #11.
This commit is contained in:
parent
a2eaa80d08
commit
6960ae6ba9
80
Cargo.lock
generated
80
Cargo.lock
generated
|
@ -29,20 +29,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e996dc7940838b7ef1096b882e29ec30a3149a3a443cdc8dba19ed382eca1fe2"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"doc-comment",
|
||||
"predicates",
|
||||
"predicates-core",
|
||||
"predicates-tree",
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.6.1"
|
||||
|
@ -260,17 +246,6 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.8.0"
|
||||
|
@ -446,12 +421,6 @@ version = "0.1.12"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
|
||||
|
||||
[[package]]
|
||||
name = "difflib"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
|
@ -491,12 +460,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.6.1"
|
||||
|
@ -974,7 +937,6 @@ dependencies = [
|
|||
name = "mensa"
|
||||
version = "0.4.2"
|
||||
dependencies = [
|
||||
"assert_cmd",
|
||||
"cacache",
|
||||
"chrono",
|
||||
"date_time_parser",
|
||||
|
@ -1226,33 +1188,6 @@ version = "0.2.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "2.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c6ce811d0b2e103743eec01db1c50612221f173084ce2f7941053e94b6bb474"
|
||||
dependencies = [
|
||||
"difflib",
|
||||
"itertools",
|
||||
"predicates-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57e35a3326b75e49aa85f5dc6ec15b41108cf5aee58eabb1f274dd18b73c2451"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "338c7be2905b732ae3984a2f40032b5e94fd8f52505b186c7d4d68d193445df7"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.0.0"
|
||||
|
@ -1796,12 +1731,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termtree"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76565a2f8df1d2170b5c365aa39d0623fd93fec20545edde299233cea82d0f16"
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
|
@ -2101,15 +2030,6 @@ version = "0.9.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.0"
|
||||
|
|
|
@ -39,4 +39,3 @@ itertools = "0.10"
|
|||
[dev-dependencies]
|
||||
pretty_assertions = "1.0"
|
||||
ssri = "7.0"
|
||||
assert_cmd = "2.0"
|
||||
|
|
49
src/cache/dummy.rs
vendored
49
src/cache/dummy.rs
vendored
|
@ -1,7 +1,7 @@
|
|||
use std::{collections::BTreeMap, sync::RwLock};
|
||||
|
||||
use cacache::Metadata;
|
||||
use ssri::{Hash, Integrity};
|
||||
use ssri::Integrity;
|
||||
|
||||
use super::Cache;
|
||||
|
||||
|
@ -10,6 +10,7 @@ use crate::{
|
|||
request::Headers,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Entry {
|
||||
meta: Metadata,
|
||||
text: String,
|
||||
|
@ -19,7 +20,9 @@ pub struct DummyCache {
|
|||
/// The real, cacache-based implementation takes only immutable references
|
||||
/// and the API is adopted to handle that. Thus we'll have to do our
|
||||
/// own interior mutability here.
|
||||
content: RwLock<BTreeMap<Hash, Entry>>,
|
||||
///
|
||||
/// This maps paths to entries.
|
||||
content: RwLock<BTreeMap<String, Entry>>,
|
||||
}
|
||||
|
||||
impl Cache for DummyCache {
|
||||
|
@ -30,18 +33,21 @@ impl Cache for DummyCache {
|
|||
}
|
||||
|
||||
fn read(&self, meta: &Metadata) -> Result<String> {
|
||||
let (algorithm, digest) = meta.integrity.to_hex();
|
||||
let hash = Hash { algorithm, digest };
|
||||
let path = path_from_integrity(&meta.integrity);
|
||||
let read = self.content.read().expect("Reading cache failed");
|
||||
let entry = read
|
||||
.get(&hash)
|
||||
.get(&path)
|
||||
.expect("BUG: Metadata exists, but entry does not!");
|
||||
eprintln!(
|
||||
"Cache read for {:?}\n-> Returning: {:#?}",
|
||||
meta.integrity, entry.text
|
||||
);
|
||||
Ok(entry.text.clone())
|
||||
}
|
||||
|
||||
fn write(&self, headers: &Headers, url: &str, text: &str) -> Result<()> {
|
||||
let mut write = self.content.write().expect("Writing cache failed");
|
||||
let hash = hash_from_key(url);
|
||||
let hash = path_from_key(url);
|
||||
let meta = assemble_meta(headers, url, text)?;
|
||||
write.insert(
|
||||
hash,
|
||||
|
@ -50,17 +56,19 @@ impl Cache for DummyCache {
|
|||
text: text.to_owned(),
|
||||
},
|
||||
);
|
||||
eprintln!(
|
||||
"Cache write to {:?}\n-> Headers: {:#?}\n-> Content: {:#?}",
|
||||
url, headers, text
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn meta(&self, url: &str) -> Result<Option<Metadata>> {
|
||||
let hash = hash_from_key(url);
|
||||
match self
|
||||
.content
|
||||
.read()
|
||||
.expect("Reading cache failed")
|
||||
.get(&hash)
|
||||
{
|
||||
let hash = path_from_key(url);
|
||||
let read = self.content.read().expect("Reading cache failed");
|
||||
let entry = read.get(&hash);
|
||||
eprintln!("Cache Metadata for {:?}: {:?}", url, entry);
|
||||
match entry {
|
||||
Some(entry) => Ok(Some(clone_metadata(&entry.meta))),
|
||||
None => Ok(None),
|
||||
}
|
||||
|
@ -68,6 +76,7 @@ impl Cache for DummyCache {
|
|||
|
||||
fn clear(&self) -> Result<()> {
|
||||
self.content.write().expect("Writing cache failed").clear();
|
||||
eprintln!("Cache cleared");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -81,14 +90,20 @@ impl Cache for DummyCache {
|
|||
}
|
||||
}
|
||||
|
||||
fn hash_from_key(key: &str) -> Hash {
|
||||
fn path_from_key(key: &str) -> String {
|
||||
let integrity = Integrity::from(key);
|
||||
hash_from_integrity(&integrity)
|
||||
let path = path_from_integrity(&integrity);
|
||||
eprintln!("Hashing key {:?} -> {:#?}", key, path);
|
||||
path
|
||||
}
|
||||
|
||||
fn hash_from_integrity(integrity: &Integrity) -> Hash {
|
||||
fn path_from_integrity(integrity: &Integrity) -> String {
|
||||
let mut path = String::new();
|
||||
let (algorithm, digest) = integrity.to_hex();
|
||||
Hash { algorithm, digest }
|
||||
path += &algorithm.to_string();
|
||||
path += &digest;
|
||||
eprintln!("Hashing integrity {:?} -> {:#?}", integrity, path);
|
||||
path
|
||||
}
|
||||
|
||||
fn clone_metadata(meta: &Metadata) -> Metadata {
|
||||
|
|
2
src/cache/fetchable.rs
vendored
2
src/cache/fetchable.rs
vendored
|
@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
|||
|
||||
use crate::error::Result;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[serde(from = "T", untagged)]
|
||||
pub enum Fetchable<T> {
|
||||
/// The value does not exist, but can be fetched.
|
||||
|
|
4
src/cache/mod.rs
vendored
4
src/cache/mod.rs
vendored
|
@ -61,6 +61,7 @@ type TextAndHeaders = (String, Headers);
|
|||
|
||||
lazy_static! {
|
||||
pub static ref CACHE: DefaultCache = DefaultCache::init().expect("Initialized cache");
|
||||
pub static ref API: DefaultApi = DefaultApi::create().expect("Failed to create API");
|
||||
}
|
||||
|
||||
/// Possible results from a cache load.
|
||||
|
@ -206,9 +207,6 @@ fn get_and_update_cache<C: Cache>(
|
|||
etag: Option<String>,
|
||||
meta: Option<Metadata>,
|
||||
) -> Result<TextAndHeaders> {
|
||||
lazy_static! {
|
||||
static ref API: DefaultApi = DefaultApi::create().expect("Failed to create API");
|
||||
}
|
||||
// Send request with optional ETag header
|
||||
let resp = API.get(url, etag)?;
|
||||
info!("Request to {:?} returned {}", url, resp.status);
|
||||
|
|
3
src/cache/tests.rs
vendored
3
src/cache/tests.rs
vendored
|
@ -33,6 +33,7 @@ fn test_cache_is_empty() {
|
|||
#[test]
|
||||
fn basic_caching() {
|
||||
let url = "http://invalid.local/test";
|
||||
API.register(url, "It works", Some("static"), Some(1), None, Some(1));
|
||||
// Cache is empty
|
||||
let val = try_load_cache(&*CACHE, url, Duration::max_value()).unwrap();
|
||||
print_cache_list("After first read").unwrap();
|
||||
|
@ -41,7 +42,7 @@ fn basic_caching() {
|
|||
let val = CACHE.fetch(url, *TTL, |txt, _| Ok(txt)).unwrap();
|
||||
assert_eq!(val, "It works",);
|
||||
// The cache should now be hit
|
||||
let val = try_load_cache(&*CACHE, url, Duration::max_value()).unwrap();
|
||||
let val = dbg!(try_load_cache(&*CACHE, url, Duration::max_value()).unwrap());
|
||||
print_cache_list("After second read").unwrap();
|
||||
assert_eq!(
|
||||
val,
|
||||
|
|
|
@ -8,6 +8,8 @@ use tracing::info;
|
|||
|
||||
mod de;
|
||||
mod ser;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use crate::{
|
||||
cache::{Cache, Fetchable, CACHE},
|
||||
|
@ -32,7 +34,7 @@ lazy_static! {
|
|||
static ref EMPTY: Vec<Meal> = Vec::new();
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[serde(from = "de::CanteenDeserialized")]
|
||||
pub struct Canteen {
|
||||
id: CanteenId,
|
||||
|
@ -44,7 +46,7 @@ pub struct Canteen {
|
|||
meals: Fetchable<HashMap<NaiveDate, Fetchable<Vec<Meal>>>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Meta {
|
||||
name: String,
|
||||
city: String,
|
||||
|
|
38
src/canteen/tests.rs
Normal file
38
src/canteen/tests.rs
Normal file
|
@ -0,0 +1,38 @@
|
|||
use chrono::Duration;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::cache::{Fetchable, API};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_parses_a_canteen() {
|
||||
let url = "http://invalid.local/canteen/1";
|
||||
let value = r#"
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Awesome Canteen",
|
||||
"city": "Lummerland",
|
||||
"address": "Some place!",
|
||||
"coordinates": [
|
||||
52.13,
|
||||
11.64
|
||||
]
|
||||
}
|
||||
"#;
|
||||
API.register(url, value, None, Some(1), None, Some(1));
|
||||
let canteen: Canteen = CACHE.fetch_json(url, Duration::zero()).unwrap();
|
||||
assert_eq!(
|
||||
canteen,
|
||||
Canteen {
|
||||
id: 1,
|
||||
meta: Fetchable::Fetched(Meta {
|
||||
name: String::from("Awesome Canteen"),
|
||||
city: String::from("Lummerland"),
|
||||
address: String::from("Some place!"),
|
||||
coordinates: Some([52.13, 11.64]),
|
||||
}),
|
||||
meals: Fetchable::None,
|
||||
}
|
||||
);
|
||||
}
|
|
@ -136,8 +136,6 @@ mod meal;
|
|||
mod pagination;
|
||||
mod request;
|
||||
mod tag;
|
||||
// #[cfg(test)]
|
||||
// mod tests;
|
||||
|
||||
use crate::{
|
||||
cache::CACHE,
|
||||
|
|
|
@ -27,14 +27,14 @@ lazy_static! {
|
|||
static ref PRE: String = color!(if_plain!(" ┊", " |"); bright_black);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||
#[serde(from = "de::Meal")]
|
||||
pub struct Meal {
|
||||
pub id: MealId,
|
||||
pub meta: Fetchable<Meta>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
pub struct Meta {
|
||||
pub name: String,
|
||||
pub tags: HashSet<Tag>,
|
||||
|
@ -43,7 +43,7 @@ pub struct Meta {
|
|||
pub category: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
||||
#[cfg_attr(debug, serde(deny_unknown_fields))]
|
||||
pub struct Prices {
|
||||
students: Option<f32>,
|
||||
|
|
|
@ -1,47 +1,92 @@
|
|||
//! This contains the [`DummyApi`] used for testing purposes.
|
||||
use std::{collections::HashMap, sync::RwLock};
|
||||
|
||||
use reqwest::StatusCode;
|
||||
|
||||
use crate::error::Result;
|
||||
|
||||
use super::{Api, Headers, Response};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct KnownResp {
|
||||
etag: Option<String>,
|
||||
value: String,
|
||||
this_page: Option<usize>,
|
||||
next_page: Option<String>,
|
||||
last_page: Option<usize>,
|
||||
}
|
||||
|
||||
/// A dummy API, serving local, deterministic Responses
|
||||
#[derive(Debug)]
|
||||
pub struct DummyApi;
|
||||
pub struct DummyApi {
|
||||
known: RwLock<HashMap<String, KnownResp>>,
|
||||
}
|
||||
|
||||
impl Api for DummyApi {
|
||||
fn create() -> Result<Self> {
|
||||
Ok(DummyApi)
|
||||
Ok(DummyApi {
|
||||
known: RwLock::new(HashMap::new()),
|
||||
})
|
||||
}
|
||||
|
||||
fn get<'url, S>(&self, url: &'url str, etag: Option<S>) -> Result<Response<'url>>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
if url == "http://invalid.local/test" {
|
||||
get_test_page(etag)
|
||||
} else {
|
||||
panic!("BUG: Invalid url in dummy api: {:?}", url)
|
||||
let read = self.known.read().expect("Reading known urls failed");
|
||||
let etag = etag.map(|etag| etag.as_ref().to_owned());
|
||||
match read.get(url) {
|
||||
Some(resp) => {
|
||||
let resp = resp.clone();
|
||||
Ok(Response {
|
||||
url,
|
||||
status: status_from_etags(&resp.etag, &etag),
|
||||
headers: Headers {
|
||||
etag: resp.etag,
|
||||
this_page: resp.this_page,
|
||||
next_page: resp.next_page,
|
||||
last_page: resp.last_page,
|
||||
},
|
||||
body: resp.value,
|
||||
})
|
||||
}
|
||||
None => panic!("BUG: Invalid url in dummy api: {:?}", url),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GET http://invalid.local/test
|
||||
fn get_test_page<S: AsRef<str>>(etag: Option<S>) -> Result<Response<'static>> {
|
||||
let etag = etag.map(|etag| etag.as_ref().to_owned());
|
||||
Ok(Response {
|
||||
url: "http://invalid.local/test",
|
||||
status: if etag == Some("static".into()) {
|
||||
StatusCode::NOT_MODIFIED
|
||||
} else {
|
||||
StatusCode::OK
|
||||
},
|
||||
headers: Headers {
|
||||
etag: Some("static".into()),
|
||||
this_page: Some(1),
|
||||
next_page: None,
|
||||
last_page: Some(1),
|
||||
},
|
||||
body: "It works".to_owned(),
|
||||
})
|
||||
impl DummyApi {
|
||||
pub fn register(
|
||||
&self,
|
||||
url: &str,
|
||||
value: &str,
|
||||
etag: Option<&str>,
|
||||
this_page: Option<usize>,
|
||||
next_page: Option<&str>,
|
||||
last_page: Option<usize>,
|
||||
) {
|
||||
let mut write = self.known.write().expect("Writing known urls failed");
|
||||
let etag = etag.map(str::to_owned);
|
||||
let next_page = next_page.map(str::to_owned);
|
||||
let old = write.insert(
|
||||
url.to_owned(),
|
||||
KnownResp {
|
||||
etag,
|
||||
value: value.to_owned(),
|
||||
this_page,
|
||||
next_page,
|
||||
last_page,
|
||||
},
|
||||
);
|
||||
if old.is_some() {
|
||||
panic!("Adress {:?} already registered!", url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn status_from_etags(old: &Option<String>, new: &Option<String>) -> StatusCode {
|
||||
match (old, new) {
|
||||
(Some(old), Some(new)) if old == new => StatusCode::NOT_MODIFIED,
|
||||
_ => StatusCode::OK,
|
||||
}
|
||||
}
|
||||
|
|
91
src/tests.rs
91
src/tests.rs
|
@ -1,91 +0,0 @@
|
|||
//! TODO: These tests fail when run via `nix flake check`
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use assert_cmd::Command;
|
||||
|
||||
#[test]
|
||||
pub fn cmd_mensa_meals() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show meals
|
||||
.arg("meals")
|
||||
// Use canteen id 1
|
||||
.args(&["--id", "1"])
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn cmd_mensa_meals_json() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show meals
|
||||
.arg("meals")
|
||||
// Use canteen id 1
|
||||
.args(&["--id", "1"])
|
||||
.arg("--json")
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(not(windows))]
|
||||
pub fn cmd_mensa_canteens() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show meals
|
||||
.arg("canteens")
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn cmd_mensa_canteens_json() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show meals
|
||||
.arg("canteens")
|
||||
.arg("--json")
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn cmd_mensa_tags() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show tags
|
||||
.arg("tags")
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn cmd_mensa_tags_json() {
|
||||
Command::cargo_bin("mensa")
|
||||
.unwrap()
|
||||
// Prevent loading the config
|
||||
.args(&["--config", "/does/not/exist"])
|
||||
// Show tags
|
||||
.arg("tags")
|
||||
.arg("--json")
|
||||
.timeout(Duration::from_secs(10))
|
||||
.assert()
|
||||
.success();
|
||||
}
|
Loading…
Reference in a new issue