blob: b413cbf9ef729d43b95158349c7b810b0d4d8566 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::cell::RefCell;
use std::collections::HashMap;
use sdk_metadata::JsonObject;
use crate::app::{Error, Result};
use crate::tarball::{InputTarball, OutputTarball, TarballContent};
impl TarballContent for String {
fn is_identical(&self, other: &String) -> Result<bool> {
Ok(self == other)
}
}
#[derive(Clone)]
pub struct MockInputTarball {
files: RefCell<HashMap<String, String>>,
}
impl MockInputTarball {
pub fn new() -> MockInputTarball {
MockInputTarball { files: RefCell::new(HashMap::new()) }
}
pub fn add(&self, path: &str, content: &str) {
assert!(
self.files.borrow_mut().insert(path.to_owned(), content.to_owned()).is_none(),
"Path already added: {}",
path
);
}
}
impl InputTarball<String> for MockInputTarball {
fn get_file<R>(&self, path: &str, reader: R) -> Result<()>
where
R: FnOnce(&mut String) -> Result<()>,
{
self.files
.borrow_mut()
.get_mut(path)
.ok_or_else(|| Error::ArchiveFileNotFound { name: path.to_owned() })
.map(|file_path| -> Result<()> { reader(file_path) })?
}
fn get_metadata<T: JsonObject>(&self, path: &str) -> Result<T> {
let mut contents = String::new();
self.get_file(path, |value| {
contents.push_str(value);
Ok(())
})?;
T::new(contents.as_bytes())
}
}
pub struct MockOutputTarball {
files: HashMap<String, String>,
}
impl MockOutputTarball {
pub fn new() -> MockOutputTarball {
MockOutputTarball { files: HashMap::new() }
}
pub fn assert_has_file(&self, path: &str) {
assert!(self.files.contains_key(path), "File not found: {}", path);
}
pub fn get_content(&self, path: &str) -> &String {
self.assert_has_file(path);
self.files.get(path).unwrap()
}
}
impl OutputTarball<String> for MockOutputTarball {
fn write_json<T: JsonObject>(&mut self, path: &str, content: &T) -> Result<()> {
self.write_file(path, &mut content.to_string().unwrap())
}
fn write_file(&mut self, path: &str, file: &mut String) -> Result<()> {
assert!(self.files.insert(path.to_owned(), file.clone()).is_none());
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_input_get() {
let tarball = MockInputTarball::new();
let path = "foo/bar.json";
let content = "hello world";
tarball.add(path, content);
tarball
.get_file(path, |file_content| {
assert_eq!(file_content, content);
Ok(())
})
.unwrap();
}
#[test]
fn test_input_get_nonexistent() {
let tarball = MockInputTarball::new();
let path = "foo/bar.json";
assert!(tarball
.get_file(path, |_file_content| {
assert!(false, "Should not have been called");
Ok(())
})
.is_err());
}
#[test]
#[should_panic]
fn test_input_double_add() {
let tarball = MockInputTarball::new();
let path = "foo/bar.json";
let content = "hello world";
tarball.add(path, content);
tarball.add(path, content);
}
#[test]
fn test_output_assert() {
let mut tarball = MockOutputTarball::new();
let path = "foo/bar.json";
let mut content = "hello world".to_owned();
tarball.write_file(path, &mut content).unwrap();
tarball.assert_has_file(path);
}
#[test]
#[should_panic]
fn test_output_assert_nonexistent() {
let tarball = MockOutputTarball::new();
let path = "foo/bar.json";
tarball.assert_has_file(path);
}
#[test]
#[should_panic]
fn test_output_double_write() {
let mut tarball = MockOutputTarball::new();
let path = "foo/bar.json";
let mut content = "hello world".to_owned();
tarball.write_file(path, &mut content).unwrap();
tarball.write_file(path, &mut content).unwrap();
}
}