mirror of
https://github.com/AleoHQ/leo.git
synced 2024-12-19 15:41:36 +03:00
Merge pull request #357 from AleoHQ/feature/update-features
Features for manifest updating
This commit is contained in:
commit
1b27a5d450
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
@ -96,6 +96,34 @@ jobs:
|
|||||||
command: test
|
command: test
|
||||||
args: --release --all --features ci_skip --no-fail-fast
|
args: --release --all --features ci_skip --no-fail-fast
|
||||||
|
|
||||||
|
test-package:
|
||||||
|
name: Test Package
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
rust:
|
||||||
|
- stable
|
||||||
|
- nightly
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install Rust (${{ matrix.rust }})
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: ${{ matrix.rust }}
|
||||||
|
override: true
|
||||||
|
|
||||||
|
- name: Install cargo-all-features
|
||||||
|
run: |
|
||||||
|
cargo install cargo-all-features
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: |
|
||||||
|
cd package
|
||||||
|
cargo test-all-features
|
||||||
|
|
||||||
codecov:
|
codecov:
|
||||||
name: Code Coverage
|
name: Code Coverage
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[package]
|
[project]
|
||||||
name = "fibonacci"
|
name = "fibonacci"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Returns a fibonnaci sequence"
|
description = "Returns a fibonnaci sequence"
|
||||||
|
1
examples/fibonacci/README.md
Normal file
1
examples/fibonacci/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# fibonacci
|
@ -1,4 +1,4 @@
|
|||||||
[package]
|
[project]
|
||||||
name = "hello-world"
|
name = "hello-world"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "Returns the sum of two u32 integers"
|
description = "Returns the sum of two u32 integers"
|
||||||
|
1
examples/hello-world/README.md
Normal file
1
examples/hello-world/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# hello-world
|
@ -1,4 +1,4 @@
|
|||||||
[package]
|
[project]
|
||||||
name = "pedersen-hash"
|
name = "pedersen-hash"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "A 256bit hash function"
|
description = "A 256bit hash function"
|
||||||
|
1
examples/pedersen-hash/README.md
Normal file
1
examples/pedersen-hash/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# pedersen-hash
|
@ -1,4 +1,4 @@
|
|||||||
[package]
|
[project]
|
||||||
name = "square-root"
|
name = "square-root"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "prove knowledge of the square root `a` of a number `b`"
|
description = "prove knowledge of the square root `a` of a number `b`"
|
||||||
|
1
examples/square-root/README.md
Normal file
1
examples/square-root/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# square-root
|
@ -41,3 +41,9 @@ version = "0.5"
|
|||||||
|
|
||||||
[dev-dependencies.lazy_static]
|
[dev-dependencies.lazy_static]
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "manifest_refactors" ]
|
||||||
|
manifest_refactors = [ "manifest_refactor_project", "manifest_refactor_remote" ]
|
||||||
|
manifest_refactor_project = [ ]
|
||||||
|
manifest_refactor_remote = [ ]
|
||||||
|
@ -33,14 +33,14 @@ pub struct Remote {
|
|||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Manifest {
|
pub struct Manifest {
|
||||||
pub package: Package,
|
pub project: Package,
|
||||||
pub remote: Option<Remote>,
|
pub remote: Option<Remote>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Manifest {
|
impl Manifest {
|
||||||
pub fn new(package_name: &str) -> Self {
|
pub fn new(package_name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
package: Package::new(package_name),
|
project: Package::new(package_name),
|
||||||
remote: None,
|
remote: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,19 +58,19 @@ impl Manifest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_name(&self) -> String {
|
pub fn get_package_name(&self) -> String {
|
||||||
self.package.name.clone()
|
self.project.name.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_version(&self) -> String {
|
pub fn get_package_version(&self) -> String {
|
||||||
self.package.version.clone()
|
self.project.version.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_description(&self) -> Option<String> {
|
pub fn get_package_description(&self) -> Option<String> {
|
||||||
self.package.description.clone()
|
self.project.description.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_license(&self) -> Option<String> {
|
pub fn get_package_license(&self) -> Option<String> {
|
||||||
self.package.license.clone()
|
self.project.license.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_package_remote(&self) -> Option<Remote> {
|
pub fn get_package_remote(&self) -> Option<Remote> {
|
||||||
@ -90,7 +90,7 @@ impl Manifest {
|
|||||||
|
|
||||||
fn template(&self) -> String {
|
fn template(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
r#"[package]
|
r#"[project]
|
||||||
name = "{name}"
|
name = "{name}"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "The {name} package"
|
description = "The {name} package"
|
||||||
@ -99,7 +99,7 @@ license = "MIT"
|
|||||||
[remote]
|
[remote]
|
||||||
author = "[AUTHOR]" # Add your Aleo Package Manager username, team's name, or organization's name.
|
author = "[AUTHOR]" # Add your Aleo Package Manager username, team's name, or organization's name.
|
||||||
"#,
|
"#,
|
||||||
name = self.package.name
|
name = self.project.name
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +128,11 @@ impl TryFrom<&PathBuf> for Manifest {
|
|||||||
let mut old_remote_format: Option<&str> = None;
|
let mut old_remote_format: Option<&str> = None;
|
||||||
let mut new_remote_format_exists = false;
|
let mut new_remote_format_exists = false;
|
||||||
|
|
||||||
let mut new_toml = "".to_owned();
|
// Toml file adhering to the new format.
|
||||||
|
let mut final_toml = "".to_owned();
|
||||||
|
|
||||||
|
// New Toml file format that should be written based on feature flags.
|
||||||
|
let mut refactored_toml = "".to_owned();
|
||||||
|
|
||||||
// Read each individual line of the toml file
|
// Read each individual line of the toml file
|
||||||
for line in buffer.lines() {
|
for line in buffer.lines() {
|
||||||
@ -138,6 +142,12 @@ impl TryFrom<&PathBuf> for Manifest {
|
|||||||
.split("=") // Split the line as 'remote' = '"{author}/{package_name}"'
|
.split("=") // Split the line as 'remote' = '"{author}/{package_name}"'
|
||||||
.collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"'
|
.collect::<Vec<&str>>()[1]; // Fetch just '"{author}/{package_name}"'
|
||||||
old_remote_format = Some(remote);
|
old_remote_format = Some(remote);
|
||||||
|
|
||||||
|
// Retain the old remote format if the `manifest_refactor_remote` is not enabled
|
||||||
|
if cfg!(not(feature = "manifest_refactor_remote")) {
|
||||||
|
refactored_toml += line;
|
||||||
|
refactored_toml += "\n";
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,8 +155,24 @@ impl TryFrom<&PathBuf> for Manifest {
|
|||||||
if line.starts_with("[remote]") {
|
if line.starts_with("[remote]") {
|
||||||
new_remote_format_exists = true;
|
new_remote_format_exists = true;
|
||||||
}
|
}
|
||||||
new_toml += line;
|
|
||||||
new_toml += "\n";
|
// If the old project format is being being used, update the toml file
|
||||||
|
// to use the new format instead.
|
||||||
|
if line.starts_with("[package]") {
|
||||||
|
final_toml += "[project]";
|
||||||
|
|
||||||
|
// Refactor the old project format if the `manifest_refactor_project` is enabled
|
||||||
|
match cfg!(feature = "manifest_refactor_project") {
|
||||||
|
true => refactored_toml += "[project]",
|
||||||
|
false => refactored_toml += line,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final_toml += line;
|
||||||
|
refactored_toml += line;
|
||||||
|
}
|
||||||
|
|
||||||
|
final_toml += "\n";
|
||||||
|
refactored_toml += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the remote format
|
// Update the remote format
|
||||||
@ -170,18 +196,23 @@ author = "{author}"
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Append the new remote to the bottom of the manifest file.
|
// Append the new remote to the bottom of the manifest file.
|
||||||
new_toml += &new_remote;
|
final_toml += &new_remote;
|
||||||
|
|
||||||
|
// Add the new remote format if the `manifest_refactor_remote` is enabled
|
||||||
|
if cfg!(feature = "manifest_refactor_remote") {
|
||||||
|
refactored_toml += &new_remote;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the toml file if it has been updated
|
// Rewrite the toml file if it has been updated
|
||||||
if buffer != new_toml {
|
if buffer != refactored_toml {
|
||||||
let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?;
|
let mut file = File::create(&path).map_err(|error| ManifestError::Creating(MANIFEST_FILENAME, error))?;
|
||||||
file.write_all(new_toml.as_bytes())
|
file.write_all(refactored_toml.as_bytes())
|
||||||
.map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?;
|
.map_err(|error| ManifestError::Writing(MANIFEST_FILENAME, error))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the toml file
|
// Read the toml file
|
||||||
Ok(toml::from_str(&new_toml).map_err(|error| ManifestError::Parsing(MANIFEST_FILENAME, error))?)
|
Ok(toml::from_str(&final_toml).map_err(|error| ManifestError::Parsing(MANIFEST_FILENAME, error))?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,192 +0,0 @@
|
|||||||
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
|
||||||
// This file is part of the Leo library.
|
|
||||||
|
|
||||||
// The Leo library is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// The Leo library is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use std::{
|
|
||||||
cell::RefCell,
|
|
||||||
env,
|
|
||||||
fs,
|
|
||||||
path::PathBuf,
|
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
|
||||||
};
|
|
||||||
|
|
||||||
const PACKAGE_TEST_DIRECTORY: &str = "package-testing";
|
|
||||||
|
|
||||||
thread_local! {
|
|
||||||
/// Establish a test id for each test.
|
|
||||||
static TEST_ID: RefCell<Option<usize>> = RefCell::new(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
/// Create a testing directory for packages in `target/`
|
|
||||||
static ref TEST_DIR: PathBuf = {
|
|
||||||
let mut path = env::current_exe().unwrap();
|
|
||||||
path.pop(); // Remove executable name
|
|
||||||
path.pop(); // Remove 'debug'
|
|
||||||
|
|
||||||
// Attempt to point at the `target` directory
|
|
||||||
if path.file_name().and_then(|s| s.to_str()) != Some("target") {
|
|
||||||
path.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
path.push(PACKAGE_TEST_DIRECTORY);
|
|
||||||
fs::create_dir_all(&path).unwrap();
|
|
||||||
|
|
||||||
path
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new directory for each test based on the ID of the test.
|
|
||||||
fn test_dir() -> PathBuf {
|
|
||||||
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
|
||||||
|
|
||||||
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
|
||||||
TEST_ID.with(|n| *n.borrow_mut() = Some(id));
|
|
||||||
|
|
||||||
let path: PathBuf = TEST_DIR.join(&format!("t{}", id)).into();
|
|
||||||
|
|
||||||
if path.exists() {
|
|
||||||
if let Err(e) = fs::remove_dir_all(&path) {
|
|
||||||
panic!("failed to remove {:?}: {:?}", &path, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fs::create_dir_all(&path).unwrap();
|
|
||||||
|
|
||||||
path
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tests for package initialization
|
|
||||||
mod initialize_package {
|
|
||||||
use super::*;
|
|
||||||
use leo_package::{
|
|
||||||
inputs::{InputFile, InputsDirectory, StateFile},
|
|
||||||
package::Package,
|
|
||||||
root::Manifest,
|
|
||||||
source::{LibraryFile, MainFile, SourceDirectory},
|
|
||||||
};
|
|
||||||
|
|
||||||
const TEST_PACKAGE_NAME: &str = "test-package";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_valid_package() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
|
|
||||||
// Initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_ok());
|
|
||||||
|
|
||||||
// Ensure a package is initialized at the `test_directory`
|
|
||||||
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[ignore]
|
|
||||||
fn initialize_fails_with_invalid_package_names() {
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_fails_with_existing_manifest() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
|
|
||||||
// Manually add a manifest file to the `test_directory`
|
|
||||||
Manifest::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
|
||||||
|
|
||||||
// Attempt to initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
|
||||||
|
|
||||||
// Ensure package is not initialized at the `test_directory`
|
|
||||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_fails_with_existing_library_file() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, true, &test_directory));
|
|
||||||
|
|
||||||
// Manually add a source directory and a library file to the `test_directory`
|
|
||||||
SourceDirectory::create(&test_directory).unwrap();
|
|
||||||
LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
|
||||||
|
|
||||||
// Attempt to initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory).is_err());
|
|
||||||
|
|
||||||
// Ensure package is not initialized at the `test_directory`
|
|
||||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_fails_with_existing_input_file() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
|
|
||||||
// Manually add an inputs directory and an input file to the `test_directory`
|
|
||||||
InputsDirectory::create(&test_directory).unwrap();
|
|
||||||
InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
|
||||||
|
|
||||||
// Attempt to initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
|
||||||
|
|
||||||
// Ensure package is not initialized at the `test_directory`
|
|
||||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_fails_with_existing_state_file() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
|
|
||||||
// Manually add an inputs directory and a state file to the `test_directory`
|
|
||||||
InputsDirectory::create(&test_directory).unwrap();
|
|
||||||
StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
|
||||||
|
|
||||||
// Attempt to initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
|
||||||
|
|
||||||
// Ensure package is not initialized at the `test_directory`
|
|
||||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn initialize_fails_with_existing_main_file() {
|
|
||||||
let test_directory = test_dir();
|
|
||||||
|
|
||||||
// Ensure a package can be initialized at the `test_directory`
|
|
||||||
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
|
|
||||||
// Manually add a source directory and a main file to the `test_directory`
|
|
||||||
SourceDirectory::create(&test_directory).unwrap();
|
|
||||||
MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
|
||||||
|
|
||||||
// Attempt to initialize a package at the `test_directory`
|
|
||||||
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
|
||||||
|
|
||||||
// Ensure package is not initialized at the `test_directory`
|
|
||||||
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
|
||||||
}
|
|
||||||
}
|
|
134
package/tests/initialize/initialize.rs
Normal file
134
package/tests/initialize/initialize.rs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use crate::test_dir;
|
||||||
|
use leo_package::{
|
||||||
|
inputs::{InputFile, InputsDirectory, StateFile},
|
||||||
|
package::Package,
|
||||||
|
root::Manifest,
|
||||||
|
source::{LibraryFile, MainFile, SourceDirectory},
|
||||||
|
};
|
||||||
|
|
||||||
|
const TEST_PACKAGE_NAME: &str = "test-package";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_valid_package() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
|
||||||
|
// Initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_ok());
|
||||||
|
|
||||||
|
// Ensure a package is initialized at the `test_directory`
|
||||||
|
assert!(Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn initialize_fails_with_invalid_package_names() {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_fails_with_existing_manifest() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
|
||||||
|
// Manually add a manifest file to the `test_directory`
|
||||||
|
Manifest::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||||
|
|
||||||
|
// Attempt to initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
||||||
|
|
||||||
|
// Ensure package is not initialized at the `test_directory`
|
||||||
|
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_fails_with_existing_library_file() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, true, &test_directory));
|
||||||
|
|
||||||
|
// Manually add a source directory and a library file to the `test_directory`
|
||||||
|
SourceDirectory::create(&test_directory).unwrap();
|
||||||
|
LibraryFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||||
|
|
||||||
|
// Attempt to initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, true, &test_directory).is_err());
|
||||||
|
|
||||||
|
// Ensure package is not initialized at the `test_directory`
|
||||||
|
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, true, &test_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_fails_with_existing_input_file() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
|
||||||
|
// Manually add an inputs directory and an input file to the `test_directory`
|
||||||
|
InputsDirectory::create(&test_directory).unwrap();
|
||||||
|
InputFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||||
|
|
||||||
|
// Attempt to initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
||||||
|
|
||||||
|
// Ensure package is not initialized at the `test_directory`
|
||||||
|
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_fails_with_existing_state_file() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
|
||||||
|
// Manually add an inputs directory and a state file to the `test_directory`
|
||||||
|
InputsDirectory::create(&test_directory).unwrap();
|
||||||
|
StateFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||||
|
|
||||||
|
// Attempt to initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
||||||
|
|
||||||
|
// Ensure package is not initialized at the `test_directory`
|
||||||
|
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn initialize_fails_with_existing_main_file() {
|
||||||
|
let test_directory = test_dir();
|
||||||
|
|
||||||
|
// Ensure a package can be initialized at the `test_directory`
|
||||||
|
assert!(Package::can_initialize(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
|
||||||
|
// Manually add a source directory and a main file to the `test_directory`
|
||||||
|
SourceDirectory::create(&test_directory).unwrap();
|
||||||
|
MainFile::new(TEST_PACKAGE_NAME).write_to(&test_directory).unwrap();
|
||||||
|
|
||||||
|
// Attempt to initialize a package at the `test_directory`
|
||||||
|
assert!(Package::initialize(TEST_PACKAGE_NAME, false, &test_directory).is_err());
|
||||||
|
|
||||||
|
// Ensure package is not initialized at the `test_directory`
|
||||||
|
assert!(!Package::is_initialized(TEST_PACKAGE_NAME, false, &test_directory));
|
||||||
|
}
|
17
package/tests/initialize/mod.rs
Normal file
17
package/tests/initialize/mod.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub mod initialize;
|
169
package/tests/manifest/manifest.rs
Normal file
169
package/tests/manifest/manifest.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Tests for package manifest
|
||||||
|
|
||||||
|
use crate::test_dir;
|
||||||
|
use leo_package::root::{Manifest, MANIFEST_FILENAME};
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
convert::TryFrom,
|
||||||
|
fs::File,
|
||||||
|
io::{Read, Write},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
const OLD_MANIFEST_FORMAT: &str = r#"[package]
|
||||||
|
name = "test-package"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Testing manifest updates."
|
||||||
|
license = "MIT"
|
||||||
|
remote = "author/test-package"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const NEW_REMOTE_FORMAT: &str = r#"
|
||||||
|
[remote]
|
||||||
|
author = "author"
|
||||||
|
"#;
|
||||||
|
|
||||||
|
const OLD_PROJECT_FORMAT: &str = "[package]";
|
||||||
|
const NEW_PROJECT_FORMAT: &str = "[project]";
|
||||||
|
|
||||||
|
/// Create a manifest file with outdated formatting.
|
||||||
|
fn create_outdated_manifest_file(path: PathBuf) -> PathBuf {
|
||||||
|
let mut path = path.to_owned();
|
||||||
|
if path.is_dir() {
|
||||||
|
path.push(PathBuf::from(MANIFEST_FILENAME));
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = File::create(&path).unwrap();
|
||||||
|
file.write_all(OLD_MANIFEST_FORMAT.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
path
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the manifest file into a string.
|
||||||
|
fn read_manifest_file(path: &PathBuf) -> String {
|
||||||
|
let mut file = File::open(path.clone()).unwrap();
|
||||||
|
let size = file.metadata().unwrap().len() as usize;
|
||||||
|
|
||||||
|
let mut buffer = String::with_capacity(size);
|
||||||
|
file.read_to_string(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the manifest file and check that the remote format is updated.
|
||||||
|
fn remote_is_updated(path: &PathBuf) -> bool {
|
||||||
|
let manifest_string = read_manifest_file(&path);
|
||||||
|
for line in manifest_string.lines() {
|
||||||
|
if line.starts_with("remote") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
manifest_string.contains(NEW_REMOTE_FORMAT)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Read the manifest file and check that the project format is updated.
|
||||||
|
fn project_is_updated(path: &PathBuf) -> bool {
|
||||||
|
let manifest_string = read_manifest_file(&path);
|
||||||
|
|
||||||
|
!manifest_string.contains(OLD_PROJECT_FORMAT) && manifest_string.contains(NEW_PROJECT_FORMAT)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(
|
||||||
|
any(feature = "manifest_refactor_project", feature = "manifest_refactor_remote"),
|
||||||
|
ignore
|
||||||
|
)]
|
||||||
|
fn test_manifest_no_refactors() {
|
||||||
|
// Create an outdated manifest file.
|
||||||
|
let test_directory = test_dir();
|
||||||
|
let manifest_path = create_outdated_manifest_file(test_directory);
|
||||||
|
|
||||||
|
// Load the manifest file, and discard the new struct.
|
||||||
|
let _manifest = Manifest::try_from(&manifest_path).unwrap();
|
||||||
|
|
||||||
|
// Check that the manifest file project has NOT been updated.
|
||||||
|
assert!(!project_is_updated(&manifest_path));
|
||||||
|
|
||||||
|
// Check that the manifest file remote has NOT been updated.
|
||||||
|
assert!(!remote_is_updated(&manifest_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(
|
||||||
|
any(feature = "manifest_refactor_project", not(feature = "manifest_refactor_remote")),
|
||||||
|
ignore
|
||||||
|
)]
|
||||||
|
fn test_manifest_refactor_remote() {
|
||||||
|
// Create an outdated manifest file.
|
||||||
|
let test_directory = test_dir();
|
||||||
|
let manifest_path = create_outdated_manifest_file(test_directory);
|
||||||
|
|
||||||
|
// Load the manifest file, and discard the new struct.
|
||||||
|
let _manifest = Manifest::try_from(&manifest_path).unwrap();
|
||||||
|
|
||||||
|
// Check that the manifest file project has NOT been updated.
|
||||||
|
assert!(!project_is_updated(&manifest_path));
|
||||||
|
|
||||||
|
// Check that the manifest file remote has been updated.
|
||||||
|
assert!(remote_is_updated(&manifest_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(
|
||||||
|
any(not(feature = "manifest_refactor_project"), feature = "manifest_refactor_remote"),
|
||||||
|
ignore
|
||||||
|
)]
|
||||||
|
fn test_manifest_refactor_project() {
|
||||||
|
// Create an outdated manifest file.
|
||||||
|
let test_directory = test_dir();
|
||||||
|
let manifest_path = create_outdated_manifest_file(test_directory);
|
||||||
|
|
||||||
|
// Load the manifest file, and discard the new struct.
|
||||||
|
let _manifest = Manifest::try_from(&manifest_path).unwrap();
|
||||||
|
|
||||||
|
// Check that the manifest file project has been updated.
|
||||||
|
assert!(project_is_updated(&manifest_path));
|
||||||
|
|
||||||
|
// Check that the manifest file remote has NOT been updated.
|
||||||
|
assert!(!remote_is_updated(&manifest_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg_attr(
|
||||||
|
any(
|
||||||
|
not(feature = "manifest_refactor_project"),
|
||||||
|
not(feature = "manifest_refactor_remote")
|
||||||
|
),
|
||||||
|
ignore
|
||||||
|
)]
|
||||||
|
fn test_manifest_refactors() {
|
||||||
|
// Create an outdated manifest file.
|
||||||
|
let test_directory = test_dir();
|
||||||
|
let manifest_path = create_outdated_manifest_file(test_directory);
|
||||||
|
|
||||||
|
// Load the manifest file, and discard the new struct.
|
||||||
|
let _manifest = Manifest::try_from(&manifest_path).unwrap();
|
||||||
|
|
||||||
|
// Check that the manifest file project has been updated.
|
||||||
|
assert!(project_is_updated(&manifest_path));
|
||||||
|
|
||||||
|
// Check that the manifest file remote has been updated.
|
||||||
|
assert!(remote_is_updated(&manifest_path));
|
||||||
|
}
|
17
package/tests/manifest/mod.rs
Normal file
17
package/tests/manifest/mod.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub mod manifest;
|
73
package/tests/mod.rs
Normal file
73
package/tests/mod.rs
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright (C) 2019-2020 Aleo Systems Inc.
|
||||||
|
// This file is part of the Leo library.
|
||||||
|
|
||||||
|
// The Leo library is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// The Leo library is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub mod initialize;
|
||||||
|
pub mod manifest;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use std::{
|
||||||
|
cell::RefCell,
|
||||||
|
env,
|
||||||
|
fs,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
|
const PACKAGE_TEST_DIRECTORY: &str = "package-testing";
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
/// Establish a test id for each test.
|
||||||
|
pub static TEST_ID: RefCell<Option<usize>> = RefCell::new(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
/// Create a testing directory for packages in `target/`
|
||||||
|
pub static ref TEST_DIR: PathBuf = {
|
||||||
|
let mut path = env::current_exe().unwrap();
|
||||||
|
path.pop(); // Remove executable name
|
||||||
|
path.pop(); // Remove 'debug'
|
||||||
|
|
||||||
|
// Attempt to point at the `target` directory
|
||||||
|
if path.file_name().and_then(|s| s.to_str()) != Some("target") {
|
||||||
|
path.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
path.push(PACKAGE_TEST_DIRECTORY);
|
||||||
|
fs::create_dir_all(&path).unwrap();
|
||||||
|
|
||||||
|
path
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new directory for each test based on the ID of the test.
|
||||||
|
pub(crate) fn test_dir() -> PathBuf {
|
||||||
|
static NEXT_ID: AtomicUsize = AtomicUsize::new(0);
|
||||||
|
|
||||||
|
let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
|
||||||
|
TEST_ID.with(|n| *n.borrow_mut() = Some(id));
|
||||||
|
|
||||||
|
let path: PathBuf = TEST_DIR.join(&format!("t{}", id)).into();
|
||||||
|
|
||||||
|
if path.exists() {
|
||||||
|
if let Err(e) = fs::remove_dir_all(&path) {
|
||||||
|
panic!("failed to remove {:?}: {:?}", &path, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::create_dir_all(&path).unwrap();
|
||||||
|
|
||||||
|
path
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user