robinpath 0.2.0

RobinPath - A lightweight, fast scripting language interpreter for automation and data processing
Documentation
use crate::executor::Environment;
use crate::value::Value;

pub fn register(env: &mut Environment) {
    env.register_builtin("test.assert", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let msg = args
            .get(1)
            .and_then(|v| v.as_str())
            .unwrap_or("Assertion failed");
        if !val.is_truthy() {
            Err(format!("Assertion failed: {}", msg))
        } else {
            Ok(Value::Null)
        }
    });

    env.register_builtin("test.assertEqual", |args, _| {
        let actual = args.first().cloned().unwrap_or(Value::Null);
        let expected = args.get(1).cloned().unwrap_or(Value::Null);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertEqual failed");

        if actual.deep_eq(&expected) {
            Ok(Value::Null)
        } else {
            Err(format!(
                "{}: expected {}, got {}",
                msg,
                expected.to_display_string(),
                actual.to_display_string()
            ))
        }
    });

    env.register_builtin("test.assertNotEqual", |args, _| {
        let actual = args.first().cloned().unwrap_or(Value::Null);
        let expected = args.get(1).cloned().unwrap_or(Value::Null);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertNotEqual failed");

        if !actual.deep_eq(&expected) {
            Ok(Value::Null)
        } else {
            Err(format!(
                "{}: values should not be equal: {}",
                msg,
                actual.to_display_string()
            ))
        }
    });

    env.register_builtin("test.assertTrue", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let msg = args
            .get(1)
            .and_then(|v| v.as_str())
            .unwrap_or("assertTrue failed");
        if val.is_truthy() {
            Ok(Value::Null)
        } else {
            Err(format!("{}", msg))
        }
    });

    env.register_builtin("test.assertFalse", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let msg = args
            .get(1)
            .and_then(|v| v.as_str())
            .unwrap_or("assertFalse failed");
        if !val.is_truthy() {
            Ok(Value::Null)
        } else {
            Err(format!("{}", msg))
        }
    });

    env.register_builtin("test.assertNull", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let msg = args
            .get(1)
            .and_then(|v| v.as_str())
            .unwrap_or("assertNull failed");
        if val.is_null() {
            Ok(Value::Null)
        } else {
            Err(format!(
                "{}: expected null, got {}",
                msg,
                val.to_display_string()
            ))
        }
    });

    env.register_builtin("test.assertNotNull", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let msg = args
            .get(1)
            .and_then(|v| v.as_str())
            .unwrap_or("assertNotNull failed");
        if !val.is_null() {
            Ok(Value::Null)
        } else {
            Err(format!("{}", msg))
        }
    });

    env.register_builtin("test.assertType", |args, _| {
        let val = args.first().cloned().unwrap_or(Value::Null);
        let expected_type = args.get(1).and_then(|v| v.as_str()).unwrap_or("");
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertType failed");
        let actual_type = val.type_of();
        if actual_type == expected_type {
            Ok(Value::Null)
        } else {
            Err(format!(
                "{}: expected type {}, got {}",
                msg, expected_type, actual_type
            ))
        }
    });

    env.register_builtin("test.assertContains", |args, _| {
        let haystack = args.first().cloned().unwrap_or(Value::Null);
        let needle = args.get(1).cloned().unwrap_or(Value::Null);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertContains failed");
        match &haystack {
            Value::String(s) => {
                let search = needle.to_display_string();
                if s.contains(&search) {
                    Ok(Value::Null)
                } else {
                    Err(format!("{}", msg))
                }
            }
            Value::Array(arr) => {
                if arr.iter().any(|v| v.deep_eq(&needle)) {
                    Ok(Value::Null)
                } else {
                    Err(format!("{}", msg))
                }
            }
            _ => Err(format!("{}", msg)),
        }
    });

    env.register_builtin("test.assertGreater", |args, _| {
        let actual = args.first().and_then(|v| v.as_number()).unwrap_or(0.0);
        let expected = args.get(1).and_then(|v| v.as_number()).unwrap_or(0.0);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertGreater failed");
        if actual > expected {
            Ok(Value::Null)
        } else {
            Err(format!("{}: {} is not greater than {}", msg, actual, expected))
        }
    });

    env.register_builtin("test.assertLess", |args, _| {
        let actual = args.first().and_then(|v| v.as_number()).unwrap_or(0.0);
        let expected = args.get(1).and_then(|v| v.as_number()).unwrap_or(0.0);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertLess failed");
        if actual < expected {
            Ok(Value::Null)
        } else {
            Err(format!("{}: {} is not less than {}", msg, actual, expected))
        }
    });

    env.register_builtin("test.assertGreaterOrEqual", |args, _| {
        let actual = args.first().and_then(|v| v.as_number()).unwrap_or(0.0);
        let expected = args.get(1).and_then(|v| v.as_number()).unwrap_or(0.0);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertGreaterOrEqual failed");
        if actual >= expected {
            Ok(Value::Null)
        } else {
            Err(format!("{}: {} is not >= {}", msg, actual, expected))
        }
    });

    env.register_builtin("test.assertLessOrEqual", |args, _| {
        let actual = args.first().and_then(|v| v.as_number()).unwrap_or(0.0);
        let expected = args.get(1).and_then(|v| v.as_number()).unwrap_or(0.0);
        let msg = args
            .get(2)
            .and_then(|v| v.as_str())
            .unwrap_or("assertLessOrEqual failed");
        if actual <= expected {
            Ok(Value::Null)
        } else {
            Err(format!("{}: {} is not <= {}", msg, actual, expected))
        }
    });
}