libwally/
test_package.rs

1//! Contains utilities for writing tests against packages.
2
3use std::{
4    collections::BTreeMap,
5    io::{Cursor, Write},
6};
7
8use zip::write::{FileOptions, ZipWriter};
9
10use crate::{
11    manifest::{Manifest, Package, Realm},
12    package_contents::PackageContents,
13    package_id::PackageId,
14    package_req::PackageReq,
15};
16
17pub struct PackageBuilder {
18    manifest: Manifest,
19    files: BTreeMap<String, String>,
20}
21
22impl PackageBuilder {
23    pub fn new<S>(identity: S) -> Self
24    where
25        S: AsRef<str>,
26    {
27        let id: PackageId = identity.as_ref().parse().expect("invalid PackageId");
28        let (name, version) = id.into_parts();
29
30        let manifest = Manifest {
31            package: Package {
32                name,
33                version,
34                registry: String::new(),
35                realm: Realm::Shared,
36                description: None,
37                license: None,
38                authors: Vec::new(),
39                include: Vec::new(),
40                exclude: Vec::new(),
41                private: false,
42            },
43            place: Default::default(),
44            dependencies: Default::default(),
45            server_dependencies: Default::default(),
46            dev_dependencies: Default::default(),
47        };
48
49        Self {
50            manifest,
51            files: BTreeMap::new(),
52        }
53    }
54
55    pub fn with_realm(mut self, realm: Realm) -> Self {
56        self.manifest.package.realm = realm;
57        self
58    }
59
60    pub fn with_dep<A, R>(mut self, alias: A, package_req: R) -> Self
61    where
62        A: Into<String>,
63        R: AsRef<str>,
64    {
65        let req: PackageReq = package_req.as_ref().parse().expect("invalid PackageReq");
66
67        self.manifest.dependencies.insert(alias.into(), req);
68        self
69    }
70
71    pub fn with_server_dep<A, R>(mut self, alias: A, package_req: R) -> Self
72    where
73        A: Into<String>,
74        R: AsRef<str>,
75    {
76        let req: PackageReq = package_req.as_ref().parse().expect("invalid PackageReq");
77
78        self.manifest.server_dependencies.insert(alias.into(), req);
79        self
80    }
81
82    pub fn with_file<P, C>(mut self, path: P, contents: C) -> Self
83    where
84        P: Into<String>,
85        C: Into<String>,
86    {
87        self.files.insert(path.into(), contents.into());
88        self
89    }
90
91    pub fn into_manifest(self) -> Manifest {
92        self.manifest
93    }
94
95    pub fn manifest(&self) -> &Manifest {
96        &self.manifest
97    }
98
99    pub fn contents(&self) -> PackageContents {
100        let mut buffer = Vec::new();
101        let mut archive = ZipWriter::new(Cursor::new(&mut buffer));
102
103        for (path, contents) in &self.files {
104            archive.start_file(path, FileOptions::default()).unwrap();
105            archive.write_all(contents.as_bytes()).unwrap();
106        }
107
108        let encoded_manifest = toml::to_string_pretty(&self.manifest).unwrap();
109        archive
110            .start_file("wally.toml", FileOptions::default())
111            .unwrap();
112        archive.write_all(encoded_manifest.as_bytes()).unwrap();
113
114        archive.finish().unwrap();
115        drop(archive);
116
117        let contents = PackageContents::from_buffer(buffer);
118        contents
119    }
120
121    pub fn package(self) -> (Manifest, PackageContents) {
122        let contents = self.contents();
123        (self.manifest, contents)
124    }
125}