81 lines
3.8 KiB
Rust
81 lines
3.8 KiB
Rust
//! The pack consumer: one pack carries grammars and themes to their consumers, installs and
|
|
//! removes as one unit, and one bad file fails the whole pack.
|
|
|
|
mod addons_support;
|
|
mod common;
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use addons_support::{Shared, TINY, entry, index_json, serve};
|
|
use common::{TempVault, temp_config, temp_vault};
|
|
use notescraft_engine::addons::{FakeTransport, FakeVerifier, INDEX_URL, Response};
|
|
use notescraft_engine::{Error, Registry, Session, register_core};
|
|
use notescraft_syntax::load;
|
|
use serde_json::{Value, json};
|
|
|
|
/// The highlighter's grammar list is process-wide, so these tests take turns.
|
|
static TURN: Mutex<()> = Mutex::new(());
|
|
|
|
const OTHER: &str = "%YAML 1.2\n---\nname: Other\nfile_extensions: [other]\nscope: source.other\ncontexts:\n main:\n - match: '\\bbar\\b'\n scope: keyword.control.other\n";
|
|
const THEME: &str = "id = \"packed\"\nname = \"Packed\"\nvariant = \"light\"\n";
|
|
|
|
struct Fixture {
|
|
reg: Registry<Session>,
|
|
session: Session,
|
|
config: std::path::PathBuf,
|
|
_guards: (TempVault, TempVault),
|
|
}
|
|
|
|
fn fixture(name: &str, files: &[(&str, &[u8])]) -> Fixture {
|
|
let (vault, config) = (temp_vault(name), temp_config(name));
|
|
let mut session = Session::open(vault.path()).unwrap();
|
|
session.use_settings_dir(config.path());
|
|
let listed = [entry("pack", "starter", "1.0.0", files, &[])];
|
|
let net = FakeTransport::new().with_response(INDEX_URL, Ok(Response { status: 200, etag: None, bytes: index_json(&listed, &[]) }));
|
|
session.set_addons_transport(Box::new(Shared(Arc::new(serve(net, "pack", "starter", "1.0.0", files)))));
|
|
session.set_addons_verifier(Box::new(FakeVerifier { accept: true }));
|
|
let mut reg = Registry::new();
|
|
register_core(&mut reg).unwrap();
|
|
let config_path = config.path().to_path_buf();
|
|
Fixture { reg, session, config: config_path, _guards: (vault, config) }
|
|
}
|
|
|
|
impl Fixture {
|
|
fn run(&mut self, id: &str, params: &Value) -> Result<Value, Error> {
|
|
self.reg.run(id, &mut self.session, params)
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn a_pack_feeds_the_grammar_and_theme_consumers_and_removes_as_one_unit() {
|
|
let _turn = TURN.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
|
|
let files: [(&str, &[u8]); 3] =
|
|
[("grammars/tiny.sublime-syntax", TINY.as_bytes()), ("grammars/other.sublime-syntax", OTHER.as_bytes()), ("themes/packed.toml", THEME.as_bytes())];
|
|
let mut f = fixture("pk-ok", &files);
|
|
f.run("registry.check", &json!({})).unwrap();
|
|
f.run("registry.install", &json!({ "kind": "pack", "id": "starter" })).unwrap();
|
|
f.session.load_grammars();
|
|
assert!(load::is_known("tiny") && load::is_known("other"));
|
|
assert_eq!(f.session.theme_named("packed").map(|t| t.name), Some("Packed".to_owned()));
|
|
f.run("registry.remove", &json!({ "kind": "pack", "id": "starter" })).unwrap();
|
|
f.session.load_grammars();
|
|
assert!(!load::is_known("tiny") && !load::is_known("other"));
|
|
assert!(f.session.theme_named("packed").is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn one_bad_file_fails_the_whole_pack() {
|
|
let _turn = TURN.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
|
|
let files: [(&str, &[u8]); 3] =
|
|
[("grammars/tiny.sublime-syntax", TINY.as_bytes()), ("grammars/other.sublime-syntax", b"not a grammar: ["), ("themes/packed.toml", THEME.as_bytes())];
|
|
let mut f = fixture("pk-bad", &files);
|
|
f.run("registry.check", &json!({})).unwrap();
|
|
assert!(f.run("registry.install", &json!({ "kind": "pack", "id": "starter" })).is_err());
|
|
f.session.load_grammars();
|
|
assert!(!load::is_known("tiny"), "the good grammar was not installed either");
|
|
assert!(f.session.theme_named("packed").is_none());
|
|
assert!(!f.config.join("registry/store/pack/starter").exists());
|
|
let state = std::fs::read_to_string(f.config.join("registry/state.json")).unwrap_or_default();
|
|
assert!(!state.contains("starter"));
|
|
}
|