runmat_runtime/testing/
objects.rs1use runmat_test::descriptor::{FixtureDescriptor, TestDescriptor};
2use runmat_test::result::{Diagnostic, TestResult};
3use runmat_value::{ObjectArray, ObjectInstance, Value};
4
5pub const TEST_CASE_CLASS: &str = "matlab.unittest.TestCase";
6pub const FUNCTION_TEST_CASE_CLASS: &str = "matlab.unittest.FunctionTestCase";
7pub const TEST_SUITE_CLASS: &str = "matlab.unittest.TestSuite";
8pub const TEST_RESULT_CLASS: &str = "matlab.unittest.TestResult";
9
10pub fn test_case_object(name: impl Into<String>, function_based: bool) -> Value {
11 let mut object = ObjectInstance::new(
12 if function_based {
13 FUNCTION_TEST_CASE_CLASS
14 } else {
15 TEST_CASE_CLASS
16 }
17 .into(),
18 );
19 object
20 .properties
21 .insert("Name".into(), Value::String(name.into()));
22 Value::Object(object)
23}
24
25pub fn test_suite_object(test: &TestDescriptor) -> Value {
26 let mut object = ObjectInstance::new(TEST_SUITE_CLASS.into());
27 object
28 .properties
29 .insert("Name".into(), Value::String(test.display_name.clone()));
30 object.properties.insert(
31 "ProcedureName".into(),
32 Value::String(
33 test.procedure
34 .display_name
35 .rsplit('/')
36 .next()
37 .unwrap_or(test.procedure.display_name.as_str())
38 .to_owned(),
39 ),
40 );
41 object.properties.insert(
42 "TestFile".into(),
43 Value::String(test.procedure.source.relative_path.clone()),
44 );
45 object.properties.insert(
46 "Tags".into(),
47 Value::StringArray(
48 runmat_value::StringArray::new(test.tags.clone(), vec![1, test.tags.len()])
49 .expect("test tags have a valid row shape"),
50 ),
51 );
52 object.properties.insert(
53 "__runmat_test_id".into(),
54 Value::String(test.id.as_str().into()),
55 );
56 Value::Object(object)
57}
58
59pub fn test_result_object(name: impl Into<String>, result: &TestResult) -> Value {
60 let mut object = ObjectInstance::new(TEST_RESULT_CLASS.into());
61 object
62 .properties
63 .insert("Name".into(), Value::String(name.into()));
64 object
65 .properties
66 .insert("Passed".into(), Value::Bool(result.state.is_success()));
67 object
68 .properties
69 .insert("Failed".into(), Value::Bool(result.state.failed));
70 object
71 .properties
72 .insert("Incomplete".into(), Value::Bool(result.state.incomplete));
73 object
74 .properties
75 .insert("Flaky".into(), Value::Bool(result.flaky));
76 object.properties.insert(
77 "Details".into(),
78 Value::String(
79 result
80 .attempts
81 .last()
82 .map(|attempt| attempt.output.clone())
83 .unwrap_or_default(),
84 ),
85 );
86 object.properties.insert(
87 "__runmat_test_id".into(),
88 Value::String(result.test_id.as_str().into()),
89 );
90 Value::Object(object)
91}
92
93pub fn fixture_object(fixture: &FixtureDescriptor) -> Value {
94 let mut object = ObjectInstance::new("matlab.unittest.fixtures.Fixture".into());
95 object
96 .properties
97 .insert("Name".into(), Value::String(fixture.display_name.clone()));
98 object.properties.insert(
99 "__runmat_fixture_id".into(),
100 Value::String(fixture.id.as_str().into()),
101 );
102 Value::Object(object)
103}
104
105pub fn diagnostic_object(diagnostic: &Diagnostic) -> Value {
106 let mut object = ObjectInstance::new("matlab.unittest.diagnostics.Diagnostic".into());
107 object.properties.insert(
108 "Identifier".into(),
109 Value::String(diagnostic.identifier.clone()),
110 );
111 object
112 .properties
113 .insert("Message".into(), Value::String(diagnostic.message.clone()));
114 Value::Object(object)
115}
116
117pub fn plugin_object(class_name: impl Into<String>) -> Value {
118 Value::Object(ObjectInstance::new(class_name.into()))
119}
120
121pub fn object_array_or_scalar(
122 class_name: impl Into<String>,
123 values: Vec<Value>,
124) -> Result<Value, String> {
125 if values.len() == 1 {
126 Ok(values.into_iter().next().expect("one value"))
127 } else {
128 ObjectArray::row(class_name, values).map(Value::ObjectArray)
129 }
130}