[−][src]Struct lab_grader::criterion::Criterion
A criterion
This is the heart of the application. Each criterion is responsible for checking one thing, and one thing only. You should build a list of criteria.
A lone Criterion
A Criterion has some informational fields (name
, messages
), a point value (worth
),
a status
, and most importantly a test
. The test takes in a reference to
TestData
and returns a bool
. The signature of every
criterion's test is always the same.
use lab_grader::*; let mut crit = Criterion::new( // Name "My First Criterion", // Worth 10, // Pass/Fail messages, a tuple ("passed", "failed"), // Test function, contained in a Box Box::new(|_: &TestData| -> bool { // test code goes here // determine if this should pass or fail true }) ); assert!(crit.status.is_none()); crit.test(); assert_eq!(crit.status, Some(true));
We can also extract the test into a function defined elsewhere. This just helps with organization.
fn my_test(_: &TestData) -> bool { // code here... true } fn main() { let mut crit = Criterion::new( "My Second Criterion", 10, ("passed", "failed"), Box::new(my_test) ); crit.test(); // ... }
We can also pass data to a criterion. This data must be a &TestData
fn my_test(data: &TestData) -> bool { if let Some(value) = data.get("key") { return value == "value" } false } fn main() { let mut crit = Criterion::new( "My Third Criterion", 10, ("passed", "failed"), Box::new(my_test) ); // Now we need some data to pass to the criterion // this crate provides a data macro that builds TestData let data = data! { "key" => "value" }; crit.test_with_data(&data); assert_eq!(crit.status, Some(true)); }
Fields
stub: String
An ID stub used to identify this criterion
name: String
A short (< 30 characters), descriptive name
worth: i16
Point value of this criterion. If it passes, this value
will be added to the Submission
grade.
Can be negative if you wish to subtract points. Be sure to get your logic right. This value is added to the submission grade if the test returns true.
messages: (String, String)
Pass or fail messages, respectively
When printing a criterion, the appropriate message will be printed. Not much use other than that.
desc: String
An optional description
test: Box<dyn Fn(&TestData) -> bool>
The criterion's test
Determines if the criterion passes or fails. This signature is required.
status: Option<bool>
If the test passed, failed, or hasn't been run.
None
if it hasn't been run, Some(true
) or Some(false
) otherwise.
If this value is Some
, the test has been run.
hide: bool
Renders the criterion unable to be printed
Implementations
impl Criterion
[src]
pub fn new<S: AsRef<str>>(
name: S,
worth: i16,
messages: (S, S),
test: Box<dyn Fn(&TestData) -> bool>
) -> Self
[src]
name: S,
worth: i16,
messages: (S, S),
test: Box<dyn Fn(&TestData) -> bool>
) -> Self
Creates a new Criterion with the given parameters.
The messages
parameter should be a tuple of
&str
containing a success then failure message, respectively.
These messages will be printed when printing the criterion.
The test
parameter is a Box
around a closure accepting
a reference to TestData returning a bool. This can get a bit confusing.
The test
closure should return true if the criterion passes, otherwise false.
The &TestData
parameter allows data from outside the closure to be passed in. TestData
is
just an alias to HashMap<String, String>
, so all keys and values must be String
s.
Example
A basic criterion
use lab_grader::{Criterion, TestData}; let mut c = Criterion::new( "A test criterion", 10, ("Success!", "Failure!"), Box::new(|_: &TestData| { // Code to test criterion goes here, // and should return false or... true }) ); assert!(c.test());
A criterion with data
let mut c = Criterion::new( "A test criterion with data!", 10, ("Success!", "Failure!"), Box::new(|data: &TestData| { return data["my_key"] == "my_value"; }) ); // The above criterion takes a `&TestData` into it's closure, // so we must establish the data to send into the closure let my_data = data! { "my_key" => "my_value" }; assert!(c.test_with_data(&my_data));
pub fn set_desc<S: AsRef<str>>(&mut self, desc: S)
[src]
Sets the description
pub fn success_message(&self) -> &String
[src]
Returns the success message, ie. the first message in the messages
tuple
pub fn failure_message(&self) -> &String
[src]
Returns the failure message, ie. the second message in the messages
tuple
pub fn hide(&mut self, state: bool)
[src]
Sets the hide
field on a criterion
If hide is true, printing the criterion with the default formatter will print nothing. Good if you want a secret criterion that the students don't know about
pub fn attach(&mut self, test: Box<dyn Fn(&TestData) -> bool>)
[src]
Sets the test method of a criterion
pub fn test_with_data(&mut self, data: &TestData) -> bool
[src]
Runs the criterion's test function with the data provided.
This is almost equivilent to calling (criterion.test)(data)
, but this
method also sets the status of the criterion to the result of the test.
You should avoid calling the test directly, and call this or the
test
method instead.
The criterion must be mutable to call this method, as the status is changed to the result of the test.
Example
let mut c = Criterion::new( "A test criterion with data!", 10, ("Success!", "Failure!"), Box::new(|data: &TestData| { return data["my_key"] == "my_value"; }) ); let my_data = data! { "my_key" => "my_value" }; c.test_with_data(&my_data); // It's either Some(true) or Some(false) since we've tested assert!(c.status.is_some());
pub fn test(&mut self) -> bool
[src]
Runs the criterions test and assigns the result to criterion.status
.
This is equivilent to running test_with_data
with
an empty TestData
.
Criterion must be mutable.
Example
let mut c = Criterion::new( "A test criterion with data!", 10, ("Success!", "Failure!"), Box::new(|_: &TestData| { true }) ); assert!(c.test()); assert!(c.status.is_some());
Trait Implementations
impl Display for Criterion
[src]
Displays the results of the criterion. You should test the criterion before printing it.
impl FromIterator<Criterion> for Criteria
[src]
fn from_iter<I: IntoIterator<Item = Criterion>>(iter: I) -> Self
[src]
Auto Trait Implementations
impl !RefUnwindSafe for Criterion
impl !Send for Criterion
impl !Sync for Criterion
impl Unpin for Criterion
impl !UnwindSafe for Criterion
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T, I> AsResult<T, I> for T where
I: Input,
I: Input,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> IntoCollection<T> for T
fn into_collection<A>(self) -> SmallVec<A> where
A: Array<Item = T>,
A: Array<Item = T>,
fn mapped<U, F, A>(self, f: F) -> SmallVec<A> where
A: Array<Item = U>,
F: FnMut(T) -> U,
A: Array<Item = U>,
F: FnMut(T) -> U,
impl<T> ToString for T where
T: Display + ?Sized,
[src]
T: Display + ?Sized,
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Typeable for T where
T: Any,
T: Any,