expy 0.0.2

Embeddable & extensible expression evaluator
Documentation
//! Very edgy tests.

use claims::*;
use expy::{BinaryOp::*, Expr, Literal, ParseError, parse};


#[test]
#[allow(illegal_floating_point_literal_pattern)]
fn literals() {
    assert_matches!(parse("1e12").unwrap(), Expr::Literal(Literal::Float(1e12)));
    assert_matches!(parse("1e+8").unwrap(), Expr::Literal(Literal::Float(1e8)));
    assert_matches!(parse("42.").unwrap(), Expr::Literal(Literal::Float(42.)));
    assert_matches!(parse("1.e-9").unwrap(), Expr::Literal(Literal::Float(1e-9)));
    assert_eq!(parse("@true").unwrap(), Expr::Literal(Literal::symbol("true")));
    assert_eq!(parse("@_").unwrap(), Expr::Literal(Literal::symbol("_")));

    // these aren't literals
    assert_eq!(parse("True").unwrap(), Expr::ref_("True"));
    assert_eq!(parse("e12").unwrap(), Expr::ref_("e12"));
    assert_eq!(parse("e+8").unwrap(), Expr::binary(Add, Expr::ref_("e"), Expr::literal(8)));
}

#[test]
fn terms() {
    assert_eq!(parse("_").unwrap(), Expr::ref_("_"));
    assert_eq!(parse("__").unwrap(), Expr::ref_("__"));
    assert_eq!(parse("_foo").unwrap(), Expr::ref_("_foo"));
    assert_eq!(parse("__magic__").unwrap(), Expr::ref_("__magic__"));
    assert_eq!(parse("_1").unwrap(), Expr::ref_("_1"));

    assert_matches!(parse("42identifier").unwrap_err(), ParseError::Syntax(_));
    if cfg!(glam) {
        assert_eq!(parse("[]").unwrap_err(), ParseError::Unsupported("vector of length 0".into()));
    }
    assert_matches!(parse("()").unwrap_err(), ParseError::Syntax(_))
}

// TODO: weird subscript cases

#[test]
fn suffix_member_accesses() {
    assert_eq!(parse("_._").unwrap(), Expr::access(Expr::ref_("_"), "_"));
    assert_eq!(parse("_1._1").unwrap(), Expr::access(Expr::ref_("_1"), "_1"));
    assert_eq!(parse("@_._").unwrap(), Expr::access(Expr::literal(Literal::symbol("_")), "_"));

    assert_matches!(parse("42._").unwrap_err(), ParseError::Syntax(_));
    assert_eq!(parse("(42)._").unwrap(), Expr::access(Expr::literal(42), "_"));

    assert_matches!(parse("1.e").unwrap_err(), ParseError::Syntax(_));
    assert_eq!(parse("(1).e").unwrap(), Expr::access(Expr::literal(1), "e"));

    // float syntax can be similar to accessing a member `e`, but it's unambiguous
    assert_eq!(parse("1.e+12").unwrap(), Expr::literal(1e12));
}