Path: blob/main/cranelift/reader/src/testcommand.rs
2450 views
//! Test commands.1//!2//! A `.clif` file can begin with one or more *test commands* which specify what is to be tested.3//! The general syntax is:4//!5//! <pre>6//! test <i><command></i> <i>[options]</i>...7//! </pre>8//!9//! The options are either a single identifier flag, or setting values like `identifier=value`.10//!11//! The parser does not understand the test commands or which options are valid. It simply parses12//! the general format into a `TestCommand` data structure.1314use std::fmt::{self, Display, Formatter};1516/// A command appearing in a test file.17#[derive(Clone, PartialEq, Eq, Debug)]18pub struct TestCommand<'a> {19/// The command name as a string.20pub command: &'a str,21/// The options following the command name.22pub options: Vec<TestOption<'a>>,23}2425/// An option on a test command.26#[derive(Clone, PartialEq, Eq, Debug)]27pub enum TestOption<'a> {28/// Single identifier flag: `foo`.29Flag(&'a str),30/// A value assigned to an identifier: `foo=bar`.31Value(&'a str, &'a str),32}3334impl<'a> TestCommand<'a> {35/// Create a new TestCommand by parsing `s`.36/// The returned command contains references into `s`.37pub fn new(s: &'a str) -> Self {38let mut parts = s.split_whitespace();39let cmd = parts.next().unwrap_or("");40Self {41command: cmd,42options: parts43.filter(|s| !s.is_empty())44.map(TestOption::new)45.collect(),46}47}48}4950impl<'a> Display for TestCommand<'a> {51fn fmt(&self, f: &mut Formatter) -> fmt::Result {52write!(f, "{}", self.command)?;53for opt in &self.options {54write!(f, " {opt}")?;55}56writeln!(f)57}58}5960impl<'a> TestOption<'a> {61/// Create a new TestOption by parsing `s`.62/// The returned option contains references into `s`.63pub fn new(s: &'a str) -> Self {64match s.find('=') {65None => TestOption::Flag(s),66Some(p) => TestOption::Value(&s[0..p], &s[p + 1..]),67}68}69}7071impl<'a> Display for TestOption<'a> {72fn fmt(&self, f: &mut Formatter) -> fmt::Result {73match *self {74TestOption::Flag(s) => write!(f, "{s}"),75TestOption::Value(s, v) => write!(f, "{s}={v}"),76}77}78}7980#[cfg(test)]81mod tests {82use super::*;8384#[test]85fn parse_option() {86assert_eq!(TestOption::new(""), TestOption::Flag(""));87assert_eq!(TestOption::new("foo"), TestOption::Flag("foo"));88assert_eq!(TestOption::new("foo=bar"), TestOption::Value("foo", "bar"));89}9091#[test]92fn parse_command() {93assert_eq!(&TestCommand::new("").to_string(), "\n");94assert_eq!(&TestCommand::new("cat").to_string(), "cat\n");95assert_eq!(&TestCommand::new("cat ").to_string(), "cat\n");96assert_eq!(&TestCommand::new("cat 1 ").to_string(), "cat 1\n");97assert_eq!(98&TestCommand::new("cat one=4 two t").to_string(),99"cat one=4 two t\n"100);101}102}103104105