From ba04e71db20d47e021982fc99950443a9350ffe3 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Wed, 17 Feb 2021 08:54:53 +0200 Subject: refactor: rewrite check in Python as check.py The old shell script became too hard to understand and maintain. This should be clearer and also more robust. --- check | 397 +++++++++++++++++++++++++----------- subplotlib/tests/files.rs | 507 ++++++++++++++++++++++++++++------------------ 2 files changed, 592 insertions(+), 312 deletions(-) diff --git a/check b/check index d41c9ae..2573a9e 100755 --- a/check +++ b/check @@ -1,113 +1,284 @@ -#!/bin/sh - -set -eu - -verbose=false -if [ "$#" -gt 0 ] -then - case "$1" in - verbose | -v | --verbose) - verbose=true - ;; - esac -fi - -hideok= -if command -v chronic > /dev/null -then - hideok=chronic -fi -quiet=-q -if $verbose -then - quiet= - hideok= -fi - -TOPDIR=$(pwd) - -_codegen() { - $hideok cargo run $quiet --package subplot --bin sp-codegen -- \ - "$1" --output "$2" --resources "${TOPDIR}/share" -} - -codegen() { - _codegen "$1" "$2" - rm -f test.log - template="$(sed -n '/^template: /s///p' "$1" | tail -n1)" - case "$template" in - python) $hideok python3 "$2" --log test.log ;; - bash) $hideok bash "$2" ;; - *) echo "Don't know interpreter for $2" ; exit 1 ;; - esac -} - -docgen() { - cargo run $quiet --package subplot --bin sp-docgen -- "$1" --output "$2" --resources "${TOPDIR}/share" -} - -# Run unit tests for the Python template. -(set -eu - cd share/python/template - for x in *_tests.py - do - $hideok echo "Unit tests: $x" - $hideok python3 "$x" - $hideok echo - done) - -if command -v flake8 > /dev/null -then - $hideok flake8 share/python/template share/python/lib/*.py -fi - -if command -v shellcheck > /dev/null -then - shellcheck check ./*.sh - find share/bash/template -name '*.sh' -exec shellcheck '{}' + -fi - -$hideok cargo build --all-targets -if cargo --list | awk '{ print $1 }' | grep 'clippy$' > /dev/null -then - cargo clippy $quiet -fi -$hideok cargo test $quiet - -if command -v rustfmt > /dev/null -then - cargo fmt --all -- --check -fi - -if command -v black > /dev/null -then - $hideok find . -type f -name '*.py' ! -name template.py ! -name test.py \ - -exec black --check '{}' + -fi - -(cd subplotlib; - $hideok cargo test --lib - for md in [!CR]*.md; do - $hideok echo "subplotlib/$md =====================================" - $hideok mkdir -p tests - _codegen "$md" "tests/$(basename "$md" .md).rs" "" - # This formatting is fine because we checked --all earlier - # so all it'll do is tidy up the test suite - cargo fmt - docgen "$md" "$(basename "$md" .md).pdf" - docgen "$md" "$(basename "$md" .md).html" - $hideok cargo test --test "$(basename "$md" .md)" - $hideok echo - done -) - -for md in [!CR]*.md share/python/lib/*.md -do - $hideok echo "$md =====================================" - codegen "$md" test.py - docgen "$md" "$(basename "$md" .md).pdf" - docgen "$md" "$(basename "$md" .md).html" - $hideok echo -done - -echo "Everything seems to be in order." +#!/usr/bin/env python3 + +import argparse +import glob +import os +import sys + +from subprocess import PIPE, DEVNULL, STDOUT + + +class Runcmd: + """Run external commands in various ways""" + + def __init__(self, verbose, progress): + self._verbose = verbose + self._progress = progress + + def _write_msg(self, msg): + sys.stdout.write(f"{msg}\n") + sys.stdout.flush() + + def msg(self, msg): + if self._verbose: + self._write_msg(msg) + + def title(self, title): + if self._verbose: + self._write_msg("") + self._write_msg("=" * len(title)) + self._write_msg(title) + self._write_msg("=" * len(title)) + elif self._progress: + self._write_msg(title) + + def _runcmd_unchecked(self, argv, **kwargs): + """Run a command (generic version) + + Return a subcommand.CompletedProcess. It's the caller's duty + check that the command succeeded. + + All actual execution of other programs happens via this method. + However, only methods of this class should ever call this + method. + """ + + # Import "run" here so that no other part of the code can see the + # symbol. + from subprocess import run + + self.msg(f"RUN: {argv} {kwargs}") + + if not self._verbose: + kwargs["stdout"] = PIPE + kwargs["stderr"] = STDOUT + + return run(argv, **kwargs) + + def runcmd(self, argv, **kwargs): + """Run a command (generic version) + + If the command fails, terminate the program. On success, return + a subprocess.CompletedProcess. + """ + + p = self._runcmd_unchecked(argv, **kwargs) + if p.returncode != 0: + sys.stdout.write((p.stdout or b"").decode("UTF-8")) + sys.stderr.write((p.stderr or b"").decode("UTF-8")) + sys.stderr.write(f"Command {argv} failed\n") + sys.exit(p.returncode) + return p + + def runcmd_maybe(self, argv, **kwargs): + """Run a command it's availbe, or quietly do no nothing""" + if self.got_command(argv[0]): + self.runcmd(argv, **kwargs) + + def got_command(self, name): + """Is a command of a given name available?""" + p = self._runcmd_unchecked(["which", name], stdout=DEVNULL) + return p.returncode == 0 + + def cargo(self, args, **kwargs): + """Run cargo with arguments.""" + self.runcmd(["cargo"] + args, **kwargs) + + def cargo_maybe(self, args, **kwargs): + """Run cargo if the desired subcommand is available""" + if self.got_cargo(args[0]): + self.runcmd(["cargo"] + args, **kwargs) + + def got_cargo(self, subcommand): + """Is a cargo subcommand available?""" + p = self.runcmd(["cargo", "--list"], check=True, stdout=PIPE) + lines = [line.strip() for line in p.stdout.decode("UTF-8").splitlines()] + return subcommand in lines + + def codegen(self, md, output, **kwargs): + """Run the Subplot code generator and the test program it produces""" + self.cargo( + [ + "run", + "--package=subplot", + "--bin=sp-codegen", + "--", + md, + f"--output={output}", + f"--resources={os.path.abspath('share')}", + ], + **kwargs, + ) + + def docgen(self, md, output, **kwargs): + """Run the Subplot document generator""" + self.cargo( + [ + "run", + "--package=subplot", + "--bin=sp-docgen", + "--", + md, + f"--output={output}", + f"--resources={os.path.abspath('share')}", + ], + **kwargs, + ) + + +def find_files(pattern, pred): + """Find files recursively, if they are accepted by a predicate function""" + return [f for f in glob.glob(pattern, recursive=True) if pred(f)] + + +def check_python(r): + """Run all checks for Python code""" + r.title("checking Python code") + + # Find all Python files anywhere, except those we know aren't proper Python. + py = find_files( + "**/*.py", lambda f: os.path.basename(f) not in ("template.py", "test.py") + ) + + # Test with flake8 if available. Flake8 finds Python files itself. + r.runcmd_maybe(["flake8", "check"] + py) + + # Check formatting with Black. We need to provide the files to Python + # ourselves. + r.runcmd_maybe(["black", "--check"] + py) + + # Find and run unit tests. + tests = find_files("**/*_tests.py", lambda f: True) + for test in tests: + dirname = os.path.dirname(test) + test = os.path.basename(test) + r.runcmd(["python3", test], cwd=dirname) + + +def check_shell(r): + """Run all checks for shell code""" + r.title("checking shell code") + + # Find all shell files anywhere, except generated test programs. + sh = find_files("**/*.sh", lambda f: os.path.basename(f) != "test.sh") + + r.runcmd_maybe(["shellcheck"] + sh) + + +def check_rust(r): + """Run all checks for Rust code""" + r.title("checking Rust code") + + r.runcmd(["cargo", "build", "--all-targets"]) + if r.got_cargo("clippy"): + r.runcmd(["cargo", "clippy"]) + r.runcmd(["cargo", "test"]) + r.runcmd(["cargo", "fmt"]) + + +def check_subplots(r): + """Run all Subplots and generate documents for them""" + mds = find_files("**/*.md", lambda f: f == f.lower() and "subplotlib" not in f) + for md0 in mds: + r.title(f"checking subplot {md0}") + + dirname = os.path.dirname(md0) or "." + md = os.path.basename(md0) + + template = get_template(md0) + if template == "python": + # Remove test log from previous run, if any. + test_log = os.path.join(dirname, "test.log") + if os.path.exists(test_log): + os.remove(test_log) + + r.codegen(md, "test.py", cwd=dirname) + r.runcmd(["python3", "test.py", "--log", "test.log"], cwd=dirname) + os.remove(test_log) + os.remove(os.path.join(dirname, "test.py")) + elif template == "bash": + r.codegen(md, "test.sh", cwd=dirname) + r.runcmd(["bash", "-x", "test.sh"], cwd=dirname) + os.remove(os.path.join(dirname, "test.sh")) + else: + sys.exit(f"unknown template {template} in {md0}") + + base, _ = os.path.splitext(md) + r.docgen(md, base + ".pdf", cwd=dirname) + r.docgen(md, base + ".html", cwd=dirname) + + +def check_subplotlib(r): + """Run all checks for subplotlib""" + r.title("checking subplotlib code") + + # Run Rust tests for the subplotlib library. + r.runcmd(["cargo", "test", "--lib"], cwd="subplotlib") + + # Find subplots for subplotlib. + mds = find_files("subplotlib/*.md", lambda f: True) + + os.makedirs("subplotlib/tests", exist_ok=True) + for md0 in mds: + r.title(f"checking subplot {md0}") + dirname = os.path.dirname(md0) + md = os.path.basename(md0) + base, _ = os.path.splitext(md) + test_rs = os.path.join("tests", base + ".rs") + r.codegen(md, test_rs, cwd=dirname) + r.cargo(["fmt"], cwd=dirname) + r.cargo(["test", "--test", base], cwd=dirname) + r.docgen(md, base + ".html", cwd=dirname) + r.docgen(md, base + ".pdf", cwd=dirname) + + +def get_template(filename): + prefix = "template: " + with open(filename) as f: + data = f.read() + for line in data.splitlines(): + if line.startswith(prefix): + line = line[len(prefix) :] + return line + sys.exit(f"{filename} does not specify a template") + + +def parse_args(): + """Parse command line arguments to this script""" + p = argparse.ArgumentParser() + p.add_argument("-v", dest="verbose", action="store_true", help="be verbose") + p.add_argument( + "-p", dest="progress", action="store_true", help="print some progress output" + ) + + all_whats = ["python", "shell", "rust", "subplots", "subplotlib"] + p.add_argument( + "what", nargs="*", default=all_whats, help=f"what to test: {all_whats}" + ) + return p.parse_args() + + +def main(): + """Main program""" + args = parse_args() + + r = Runcmd(args.verbose, args.progress) + + for what in args.what: + if what == "python": + check_python(r) + elif what == "shell": + check_shell(r) + elif what == "rust": + check_rust(r) + elif what == "subplots": + check_subplots(r) + elif what == "subplotlib": + check_subplotlib(r) + else: + sys.exit(f"Unknown test {what}") + + sys.stdout.write("Everything seems to be in order.\n") + + +main() diff --git a/subplotlib/tests/files.rs b/subplotlib/tests/files.rs index a8fce3d..2f0bc6c 100644 --- a/subplotlib/tests/files.rs +++ b/subplotlib/tests/files.rs @@ -1,70 +1,90 @@ use subplotlib::prelude::*; + + // -------------------------------- lazy_static! { - static ref SUBPLOT_EMBEDDED_FILES: Vec = - vec![SubplotDataFile::new("aGVsbG8udHh0", "aGVsbG8sIHdvcmxkCg=="),]; + static ref SUBPLOT_EMBEDDED_FILES: Vec = vec![ + + SubplotDataFile::new("aGVsbG8udHh0", + "aGVsbG8sIHdvcmxkCg=="), + + ]; } + + // --------------------------------- // Create on-disk files from embedded files #[test] fn create_on_disk_files_from_embedded_files() { - let mut scenario = Scenario::new(&base64_decode( - "Q3JlYXRlIG9uLWRpc2sgZmlsZXMgZnJvbSBlbWJlZGRlZCBmaWxlcw==", - )); - + let mut scenario = Scenario::new(&base64_decode("Q3JlYXRlIG9uLWRpc2sgZmlsZXMgZnJvbSBlbWJlZGRlZCBmaWxlcw==")); + let step = subplotlib::steplibrary::files::create_from_embedded::Builder::default() - .embedded_file({ - use std::path::PathBuf; - // hello.txt - let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); - SUBPLOT_EMBEDDED_FILES - .iter() - .find(|df| df.name() == target_name) - .expect("Unable to find file at runtime") - .clone() - }) - .build(); + .embedded_file( + + { + use std::path::PathBuf; + // hello.txt + let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); + SUBPLOT_EMBEDDED_FILES + .iter() + .find(|df| df.name() == target_name) + .expect("Unable to find file at runtime") + .clone() + } + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_exists::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_contains::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .data( + ) + .data( + // "hello, world" - &base64_decode("aGVsbG8sIHdvcmxk"), + &base64_decode("aGVsbG8sIHdvcmxk" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_does_not_exist::Builder::default() - .filename( + .filename( + // "other.txt" - &base64_decode("b3RoZXIudHh0"), + &base64_decode("b3RoZXIudHh0" + ) ) - .build(); + .build(); scenario.add_step(step, None); - - let step = - subplotlib::steplibrary::files::create_from_embedded_with_other_name::Builder::default() - .filename_on_disk( - // "other.txt" - &base64_decode("b3RoZXIudHh0"), - ) - .embedded_file({ + + let step = subplotlib::steplibrary::files::create_from_embedded_with_other_name::Builder::default() + .filename_on_disk( + + // "other.txt" + &base64_decode("b3RoZXIudHh0" + ) + ) + .embedded_file( + + { use std::path::PathBuf; // hello.txt let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); @@ -73,293 +93,369 @@ fn create_on_disk_files_from_embedded_files() { .find(|df| df.name() == target_name) .expect("Unable to find file at runtime") .clone() - }) - .build(); + } + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_exists::Builder::default() - .filename( + .filename( + // "other.txt" - &base64_decode("b3RoZXIudHh0"), + &base64_decode("b3RoZXIudHh0" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_match::Builder::default() - .filename1( + .filename1( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" + ) ) - .filename2( + .filename2( + // "other.txt" - &base64_decode("b3RoZXIudHh0"), + &base64_decode("b3RoZXIudHh0" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::only_these_exist::Builder::default() - .filenames( + .filenames( + // "hello.txt, other.txt" - &base64_decode("aGVsbG8udHh0LCBvdGhlci50eHQ="), + &base64_decode("aGVsbG8udHh0LCBvdGhlci50eHQ=" ) - .build(); + ) + .build(); scenario.add_step(step, None); + scenario.run().unwrap(); } + // --------------------------------- // File metadata #[test] fn file_metadata() { let mut scenario = Scenario::new(&base64_decode("RmlsZSBtZXRhZGF0YQ==")); - + let step = subplotlib::steplibrary::files::create_from_embedded::Builder::default() - .embedded_file({ - use std::path::PathBuf; - // hello.txt - let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); - SUBPLOT_EMBEDDED_FILES - .iter() - .find(|df| df.name() == target_name) - .expect("Unable to find file at runtime") - .clone() - }) - .build(); + .embedded_file( + + { + use std::path::PathBuf; + // hello.txt + let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); + SUBPLOT_EMBEDDED_FILES + .iter() + .find(|df| df.name() == target_name) + .expect("Unable to find file at runtime") + .clone() + } + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::remember_metadata::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::has_remembered_metadata::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::create_from_text::Builder::default() - .text( + .text( + // "yo" - &base64_decode("eW8="), + &base64_decode("eW8=" ) - .filename( + ) + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::has_different_metadata::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" + ) ) - .build(); + .build(); scenario.add_step(step, None); + scenario.run().unwrap(); } + // --------------------------------- // File modification time #[test] fn file_modification_time() { let mut scenario = Scenario::new(&base64_decode("RmlsZSBtb2RpZmljYXRpb24gdGltZQ==")); - + let step = subplotlib::steplibrary::files::touch_with_timestamp::Builder::default() - .filename( + .filename( + // "foo.dat" - &base64_decode("Zm9vLmRhdA=="), + &base64_decode("Zm9vLmRhdA==" ) - .mtime( + ) + .mtime( + // "1970-01-02 03:04:05" - &base64_decode("MTk3MC0wMS0wMiAwMzowNDowNQ=="), + &base64_decode("MTk3MC0wMS0wMiAwMzowNDowNQ==" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::mtime_is_ancient::Builder::default() - .filename( + .filename( + // "foo.dat" - &base64_decode("Zm9vLmRhdA=="), + &base64_decode("Zm9vLmRhdA==" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::touch::Builder::default() - .filename( + .filename( + // "foo.dat" - &base64_decode("Zm9vLmRhdA=="), + &base64_decode("Zm9vLmRhdA==" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::mtime_is_recent::Builder::default() - .filename( + .filename( + // "foo.dat" - &base64_decode("Zm9vLmRhdA=="), + &base64_decode("Zm9vLmRhdA==" ) - .build(); + ) + .build(); scenario.add_step(step, None); + scenario.run().unwrap(); } + // --------------------------------- // File contents #[test] fn file_contents() { let mut scenario = Scenario::new(&base64_decode("RmlsZSBjb250ZW50cw==")); - + let step = subplotlib::steplibrary::files::create_from_embedded::Builder::default() - .embedded_file({ - use std::path::PathBuf; - // hello.txt - let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); - SUBPLOT_EMBEDDED_FILES - .iter() - .find(|df| df.name() == target_name) - .expect("Unable to find file at runtime") - .clone() - }) - .build(); + .embedded_file( + + { + use std::path::PathBuf; + // hello.txt + let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); + SUBPLOT_EMBEDDED_FILES + .iter() + .find(|df| df.name() == target_name) + .expect("Unable to find file at runtime") + .clone() + } + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_contains::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .data( + ) + .data( + // "hello, world" - &base64_decode("aGVsbG8sIHdvcmxk"), + &base64_decode("aGVsbG8sIHdvcmxk" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_matches_regex::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" + ) ) - .regex( + .regex( + // "hello, .*" - &base64_decode("aGVsbG8sIC4q"), + &base64_decode("aGVsbG8sIC4q" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::file_matches_regex::Builder::default() - .filename( + .filename( + // "hello.txt" - &base64_decode("aGVsbG8udHh0"), + &base64_decode("aGVsbG8udHh0" ) - .regex( + ) + .regex( + // "hello, .*" - &base64_decode("aGVsbG8sIC4q"), + &base64_decode("aGVsbG8sIC4q" + ) ) - .build(); + .build(); scenario.add_step(step, None); + scenario.run().unwrap(); } + // --------------------------------- // Directories #[test] fn directories() { let mut scenario = Scenario::new(&base64_decode("RGlyZWN0b3JpZXM=")); - + let step = subplotlib::steplibrary::files::make_directory::Builder::default() - .path( + .path( + // "first" - &base64_decode("Zmlyc3Q="), + &base64_decode("Zmlyc3Q=" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_exists::Builder::default() - .path( + .path( + // "first" - &base64_decode("Zmlyc3Q="), + &base64_decode("Zmlyc3Q=" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_is_empty::Builder::default() - .path( + .path( + // "first" - &base64_decode("Zmlyc3Q="), + &base64_decode("Zmlyc3Q=" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_does_not_exist::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::remove_directory::Builder::default() - .path( + .path( + // "first" - &base64_decode("Zmlyc3Q="), + &base64_decode("Zmlyc3Q=" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_does_not_exist::Builder::default() - .path( + .path( + // "first" - &base64_decode("Zmlyc3Q="), + &base64_decode("Zmlyc3Q=" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::make_directory::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_exists::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_is_empty::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); - - let step = - subplotlib::steplibrary::files::create_from_embedded_with_other_name::Builder::default() - .filename_on_disk( - // "second/third/hello.txt" - &base64_decode("c2Vjb25kL3RoaXJkL2hlbGxvLnR4dA=="), - ) - .embedded_file({ + + let step = subplotlib::steplibrary::files::create_from_embedded_with_other_name::Builder::default() + .filename_on_disk( + + // "second/third/hello.txt" + &base64_decode("c2Vjb25kL3RoaXJkL2hlbGxvLnR4dA==" + ) + ) + .embedded_file( + + { use std::path::PathBuf; // hello.txt let target_name: PathBuf = base64_decode("aGVsbG8udHh0").into(); @@ -368,49 +464,62 @@ fn directories() { .find(|df| df.name() == target_name) .expect("Unable to find file at runtime") .clone() - }) - .build(); + } + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_is_not_empty::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" ) - .build(); + ) + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_exists::Builder::default() - .path( + .path( + // "second/third" - &base64_decode("c2Vjb25kL3RoaXJk"), + &base64_decode("c2Vjb25kL3RoaXJk" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_is_not_empty::Builder::default() - .path( + .path( + // "second/third" - &base64_decode("c2Vjb25kL3RoaXJk"), + &base64_decode("c2Vjb25kL3RoaXJk" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::remove_directory::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); - + let step = subplotlib::steplibrary::files::path_does_not_exist::Builder::default() - .path( + .path( + // "second" - &base64_decode("c2Vjb25k"), + &base64_decode("c2Vjb25k" + ) ) - .build(); + .build(); scenario.add_step(step, None); + scenario.run().unwrap(); } + -- cgit v1.2.1