tamer: obj::xmlo::air::test: Extract into own file

main
Mike Gerwitz 2023-04-20 16:35:53 -04:00
parent 6f68292df5
commit e13817c203
2 changed files with 541 additions and 523 deletions

View File

@ -391,526 +391,4 @@ impl Error for XmloAirError {
}
#[cfg(test)]
mod test {
use super::*;
use crate::{
asg::{FragmentText, IdentKind},
num::{Dim, Dtype},
obj::xmlo::{SymAttrs, SymType},
parse::Parsed,
span::dummy::*,
sym::GlobalSymbolIntern,
};
type Sut = XmloToAir;
#[test]
fn data_from_package_event() {
let name = "name".into();
let relroot = "some/path".into();
let toks = vec![
XmloToken::PkgName(SPair(name, S1)),
XmloToken::PkgRootPath(SPair(relroot, S2)),
XmloToken::Eoh(S3),
]
.into_iter();
let mut sut = Sut::parse(toks);
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgRootPath
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
assert_eq!(Some(name), ctx.prog_name);
assert_eq!(Some(relroot), ctx.relroot);
}
#[test]
fn adds_elig_as_root() {
let name = "name-root".into();
let elig_sym = "elig".into();
let toks = vec![
XmloToken::PkgName(SPair(name, S1)),
XmloToken::PkgEligClassYields(SPair(elig_sym, S2)),
XmloToken::Eoh(S3),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentRoot(SPair(elig_sym, S2))),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
#[test]
fn adds_sym_deps() {
let sym_from = "from".into();
let sym_to1 = "to1".into();
let sym_to2 = "to2".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDepStart(SPair(sym_from, S2)),
XmloToken::Symbol(SPair(sym_to1, S3)),
XmloToken::Symbol(SPair(sym_to2, S4)),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Incomplete, // SymDepStart
Parsed::Object(Air::IdentDep(
SPair(sym_from, S2),
SPair(sym_to1, S3)
)),
Parsed::Object(Air::IdentDep(
SPair(sym_from, S2),
SPair(sym_to2, S4)
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
#[test]
fn sym_decl_with_src_not_added_and_populates_found() {
let sym = "sym".into();
let src_a = "src_a".into();
let src_b = "src_b".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
src: Some(src_a),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym, S3),
SymAttrs {
src: Some(src_b),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
let mut sut = Sut::parse(toks.into_iter());
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // SymDecl (@src)
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // SymDecl (@src)
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
let mut founds = ctx.found.unwrap().into_iter().collect::<Vec<_>>();
// Just to remove nondeterminism in case the iteration order happens
// to change.
founds.sort();
assert_eq!(vec![src_a, src_b], founds);
}
#[test]
fn sym_decl_added_to_graph() {
let sym_extern = "sym_extern".into();
let sym_non_extern = "sym_non_extern".into();
let sym_map = "sym_map".into();
let sym_retmap = "sym_retmap".into();
let pkg_name = "pkg name".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(
SPair(sym_extern, S1),
SymAttrs {
pkg_name: Some(pkg_name),
extern_: true,
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_non_extern, S2),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_map, S3),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Map),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_retmap, S4),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::RetMap),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
let mut sut = Sut::parse(toks.into_iter());
// Note that each of these will have their package names cleared
// since this is considered to be the first package encountered.
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentExternDecl(
SPair(sym_extern, S1),
IdentKind::Meta,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_non_extern, S2),
IdentKind::Meta,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_map, S3),
IdentKind::Map,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_retmap, S4),
IdentKind::RetMap,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
// Both above symbols were local (no `src`),
// but note that we don't care if it's None or initialized with a
// length of 0.
assert!(ctx.found.unwrap_or_default().len() == 0);
}
// See above test, where pkg_name was cleared.
#[test]
fn sym_decl_pkg_name_retained_if_not_first() {
let sym = "sym".into();
let pkg_name = "pkg name".into();
// This is all that's needed to not consider this to be the first
// package,
// so that pkg_name is retained below.
let ctx = XmloAirContext {
first: false,
..Default::default()
};
let toks = vec![
XmloToken::PkgName(SPair(pkg_name, S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentDecl(
SPair(sym, S2),
IdentKind::Meta,
Source {
pkg_name: Some(pkg_name),
..Default::default()
}
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse_with_context(toks.into_iter(), ctx).collect(),
);
}
// This used to be set in SymAttrs by XmloReader,
// but that's no longer true with the new reader.
#[test]
fn sym_decl_pkg_name_set_if_empty_and_not_first() {
let sym = "sym".into();
let pkg_name = "pkg name".into();
let ctx = XmloAirContext {
first: false,
..Default::default()
};
let toks = vec![
XmloToken::PkgName(SPair(pkg_name, S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
// No name
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentDecl(
SPair(sym, S2),
IdentKind::Meta,
Source {
pkg_name: Some(pkg_name), // Name inherited
..Default::default()
},
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse_with_context(toks.into_iter(), ctx).collect(),
);
}
#[test]
fn ident_kind_conversion_error_propagates() {
let sym = "sym".into();
let bad_attrs = SymAttrs::default();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(SPair(sym, S2), bad_attrs),
XmloToken::Eoh(S1),
];
Sut::parse(toks.into_iter())
.collect::<Result<Vec<_>, _>>()
.expect_err("expected IdentKind conversion error");
}
#[test]
fn sets_fragment() {
let sym = "sym".into();
let frag = FragmentText::from("foo");
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::Fragment(SPair(sym, S2), frag.clone()),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentFragment(SPair(sym, S2), frag)),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
macro_rules! test_kind {
($name:ident, $src:expr => $dest:expr) => {
#[test]
fn $name() {
assert_eq!(
Ok($dest),
SymAttrs {
ty: Some($src),
..Default::default()
}
.try_into()
);
}
};
($name:ident, $src:expr => $dest:expr, dim) => {
#[test]
fn $name() {
let dim = Dim::Vector;
assert_eq!(
Ok($dest(Dim::Vector)),
SymAttrs {
ty: Some($src),
dim: Some(dim),
..Default::default()
}
.try_into()
);
// no dim
let result = IdentKind::try_from(SymAttrs {
ty: Some($src),
..Default::default()
})
.expect_err("must fail when missing dim");
assert_eq!(XmloAirError::MissingDim, result);
}
};
($name:ident, $src:expr => $dest:expr, dtype) => {
#[test]
fn $name() {
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(dtype)),
SymAttrs {
ty: Some($src),
dtype: Some(dtype),
..Default::default()
}
.try_into()
);
// no dtype
let result = IdentKind::try_from(SymAttrs {
ty: Some($src),
..Default::default()
})
.expect_err("must fail when missing dtype");
assert_eq!(XmloAirError::MissingDtype, result);
}
};
($name:ident, $src:expr => $dest:expr, dim, dtype) => {
#[test]
fn $name() {
let dim = Dim::Vector;
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(Dim::Vector, dtype)),
SymAttrs {
ty: Some($src),
dim: Some(dim),
dtype: Some(dtype),
..Default::default()
}
.try_into()
);
// no dim
let dim_result = IdentKind::try_from(SymAttrs {
ty: Some($src),
dtype: Some(dtype),
..Default::default()
})
.expect_err("must fail when missing dim");
assert_eq!(XmloAirError::MissingDim, dim_result);
// no dtype
let dtype_result = IdentKind::try_from(SymAttrs {
ty: Some($src),
dim: Some(dim),
..Default::default()
})
.expect_err("must fail when missing dtype");
assert_eq!(XmloAirError::MissingDtype, dtype_result);
}
};
}
test_kind!(cgen, SymType::Cgen => IdentKind::Cgen, dim);
test_kind!(class, SymType::Class => IdentKind::Class, dim);
test_kind!(r#const, SymType::Const => IdentKind::Const, dim, dtype);
test_kind!(func, SymType::Func => IdentKind::Func, dim, dtype);
test_kind!(gen, SymType::Gen => IdentKind::Gen, dim, dtype);
test_kind!(lparam, SymType::Lparam => IdentKind::Lparam, dim, dtype);
test_kind!(param, SymType::Param => IdentKind::Param, dim, dtype);
test_kind!(rate, SymType::Rate => IdentKind::Rate, dtype);
test_kind!(tpl, SymType::Tpl => IdentKind::Tpl);
test_kind!(r#type, SymType::Type => IdentKind::Type, dtype);
test_kind!(maphead, SymType::MapHead => IdentKind::MapHead);
test_kind!(map, SymType::Map => IdentKind::Map);
test_kind!(maptail, SymType::MapTail => IdentKind::MapTail);
test_kind!(retmaphead, SymType::RetMapHead => IdentKind::RetMapHead);
test_kind!(retmap, SymType::RetMap => IdentKind::RetMap);
test_kind!(retmaptail, SymType::RetMapTail => IdentKind::RetMapTail);
test_kind!(meta, SymType::Meta => IdentKind::Meta);
test_kind!(worksheet, SymType::Worksheet => IdentKind::Worksheet);
#[test]
fn source_from_sym_attrs() {
let nsym: SymbolId = "name".intern();
let ssym: SymbolId = "src".intern();
let psym: SymbolId = "parent".intern();
let ysym: SymbolId = "yields".intern();
let fsym: SymbolId = "from".intern();
let attrs = SymAttrs {
pkg_name: Some(nsym),
src: Some(ssym),
generated: true,
parent: Some(psym),
yields: Some(ysym),
desc: Some("sym desc".into()),
from: Some(fsym),
virtual_: true,
override_: true,
..Default::default()
};
assert_eq!(
Source {
pkg_name: Some(nsym),
src: Some(ssym),
generated: attrs.generated,
parent: attrs.parent,
yields: attrs.yields,
desc: Some("sym desc".into()),
from: Some(fsym),
virtual_: true,
override_: true,
},
attrs.into(),
);
}
}
mod test;

View File

@ -0,0 +1,540 @@
// Tests lowering `xmlo` object file into AIR
//
// Copyright (C) 2014-2023 Ryan Specialty, LLC.
//
// This file is part of TAME.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use crate::{
asg::{FragmentText, IdentKind},
num::{Dim, Dtype},
obj::xmlo::{SymAttrs, SymType},
parse::Parsed,
span::dummy::*,
sym::GlobalSymbolIntern,
};
type Sut = XmloToAir;
#[test]
fn data_from_package_event() {
let name = "name".into();
let relroot = "some/path".into();
let toks = vec![
XmloToken::PkgName(SPair(name, S1)),
XmloToken::PkgRootPath(SPair(relroot, S2)),
XmloToken::Eoh(S3),
]
.into_iter();
let mut sut = Sut::parse(toks);
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgRootPath
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
assert_eq!(Some(name), ctx.prog_name);
assert_eq!(Some(relroot), ctx.relroot);
}
#[test]
fn adds_elig_as_root() {
let name = "name-root".into();
let elig_sym = "elig".into();
let toks = vec![
XmloToken::PkgName(SPair(name, S1)),
XmloToken::PkgEligClassYields(SPair(elig_sym, S2)),
XmloToken::Eoh(S3),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentRoot(SPair(elig_sym, S2))),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
#[test]
fn adds_sym_deps() {
let sym_from = "from".into();
let sym_to1 = "to1".into();
let sym_to2 = "to2".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDepStart(SPair(sym_from, S2)),
XmloToken::Symbol(SPair(sym_to1, S3)),
XmloToken::Symbol(SPair(sym_to2, S4)),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Incomplete, // SymDepStart
Parsed::Object(Air::IdentDep(
SPair(sym_from, S2),
SPair(sym_to1, S3)
)),
Parsed::Object(Air::IdentDep(
SPair(sym_from, S2),
SPair(sym_to2, S4)
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
#[test]
fn sym_decl_with_src_not_added_and_populates_found() {
let sym = "sym".into();
let src_a = "src_a".into();
let src_b = "src_b".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
src: Some(src_a),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym, S3),
SymAttrs {
src: Some(src_b),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
let mut sut = Sut::parse(toks.into_iter());
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // SymDecl (@src)
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // SymDecl (@src)
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
let mut founds = ctx.found.unwrap().into_iter().collect::<Vec<_>>();
// Just to remove nondeterminism in case the iteration order happens
// to change.
founds.sort();
assert_eq!(vec![src_a, src_b], founds);
}
#[test]
fn sym_decl_added_to_graph() {
let sym_extern = "sym_extern".into();
let sym_non_extern = "sym_non_extern".into();
let sym_map = "sym_map".into();
let sym_retmap = "sym_retmap".into();
let pkg_name = "pkg name".into();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(
SPair(sym_extern, S1),
SymAttrs {
pkg_name: Some(pkg_name),
extern_: true,
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_non_extern, S2),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_map, S3),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Map),
..Default::default()
},
),
XmloToken::SymDecl(
SPair(sym_retmap, S4),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::RetMap),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
let mut sut = Sut::parse(toks.into_iter());
// Note that each of these will have their package names cleared
// since this is considered to be the first package encountered.
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // PkgName
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentExternDecl(
SPair(sym_extern, S1),
IdentKind::Meta,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_non_extern, S2),
IdentKind::Meta,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_map, S3),
IdentKind::Map,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(
Some(Ok(Parsed::Object(Air::IdentDecl(
SPair(sym_retmap, S4),
IdentKind::RetMap,
Source {
pkg_name: None,
..Default::default()
}
)))),
sut.next(),
);
assert_eq!(Some(Ok(Parsed::Incomplete)), sut.next()); // Eoh
let ctx = sut.finalize().unwrap().into_context();
// Both above symbols were local (no `src`),
// but note that we don't care if it's None or initialized with a
// length of 0.
assert!(ctx.found.unwrap_or_default().len() == 0);
}
// See above test, where pkg_name was cleared.
#[test]
fn sym_decl_pkg_name_retained_if_not_first() {
let sym = "sym".into();
let pkg_name = "pkg name".into();
// This is all that's needed to not consider this to be the first
// package,
// so that pkg_name is retained below.
let ctx = XmloAirContext {
first: false,
..Default::default()
};
let toks = vec![
XmloToken::PkgName(SPair(pkg_name, S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
pkg_name: Some(pkg_name),
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentDecl(
SPair(sym, S2),
IdentKind::Meta,
Source {
pkg_name: Some(pkg_name),
..Default::default()
}
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse_with_context(toks.into_iter(), ctx).collect(),
);
}
// This used to be set in SymAttrs by XmloReader,
// but that's no longer true with the new reader.
#[test]
fn sym_decl_pkg_name_set_if_empty_and_not_first() {
let sym = "sym".into();
let pkg_name = "pkg name".into();
let ctx = XmloAirContext {
first: false,
..Default::default()
};
let toks = vec![
XmloToken::PkgName(SPair(pkg_name, S1)),
XmloToken::SymDecl(
SPair(sym, S2),
SymAttrs {
// No name
ty: Some(SymType::Meta),
..Default::default()
},
),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentDecl(
SPair(sym, S2),
IdentKind::Meta,
Source {
pkg_name: Some(pkg_name), // Name inherited
..Default::default()
},
)),
Parsed::Incomplete, // Eoh
]),
Sut::parse_with_context(toks.into_iter(), ctx).collect(),
);
}
#[test]
fn ident_kind_conversion_error_propagates() {
let sym = "sym".into();
let bad_attrs = SymAttrs::default();
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::SymDecl(SPair(sym, S2), bad_attrs),
XmloToken::Eoh(S1),
];
Sut::parse(toks.into_iter())
.collect::<Result<Vec<_>, _>>()
.expect_err("expected IdentKind conversion error");
}
#[test]
fn sets_fragment() {
let sym = "sym".into();
let frag = FragmentText::from("foo");
let toks = vec![
XmloToken::PkgName(SPair("name".into(), S1)),
XmloToken::Fragment(SPair(sym, S2), frag.clone()),
XmloToken::Eoh(S1),
];
assert_eq!(
Ok(vec![
Parsed::Incomplete, // PkgName
Parsed::Object(Air::IdentFragment(SPair(sym, S2), frag)),
Parsed::Incomplete, // Eoh
]),
Sut::parse(toks.into_iter()).collect(),
);
}
macro_rules! test_kind {
($name:ident, $src:expr => $dest:expr) => {
#[test]
fn $name() {
assert_eq!(
Ok($dest),
SymAttrs {
ty: Some($src),
..Default::default()
}
.try_into()
);
}
};
($name:ident, $src:expr => $dest:expr, dim) => {
#[test]
fn $name() {
let dim = Dim::Vector;
assert_eq!(
Ok($dest(Dim::Vector)),
SymAttrs {
ty: Some($src),
dim: Some(dim),
..Default::default()
}
.try_into()
);
// no dim
let result = IdentKind::try_from(SymAttrs {
ty: Some($src),
..Default::default()
})
.expect_err("must fail when missing dim");
assert_eq!(XmloAirError::MissingDim, result);
}
};
($name:ident, $src:expr => $dest:expr, dtype) => {
#[test]
fn $name() {
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(dtype)),
SymAttrs {
ty: Some($src),
dtype: Some(dtype),
..Default::default()
}
.try_into()
);
// no dtype
let result = IdentKind::try_from(SymAttrs {
ty: Some($src),
..Default::default()
})
.expect_err("must fail when missing dtype");
assert_eq!(XmloAirError::MissingDtype, result);
}
};
($name:ident, $src:expr => $dest:expr, dim, dtype) => {
#[test]
fn $name() {
let dim = Dim::Vector;
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(Dim::Vector, dtype)),
SymAttrs {
ty: Some($src),
dim: Some(dim),
dtype: Some(dtype),
..Default::default()
}
.try_into()
);
// no dim
let dim_result = IdentKind::try_from(SymAttrs {
ty: Some($src),
dtype: Some(dtype),
..Default::default()
})
.expect_err("must fail when missing dim");
assert_eq!(XmloAirError::MissingDim, dim_result);
// no dtype
let dtype_result = IdentKind::try_from(SymAttrs {
ty: Some($src),
dim: Some(dim),
..Default::default()
})
.expect_err("must fail when missing dtype");
assert_eq!(XmloAirError::MissingDtype, dtype_result);
}
};
}
test_kind!(cgen, SymType::Cgen => IdentKind::Cgen, dim);
test_kind!(class, SymType::Class => IdentKind::Class, dim);
test_kind!(r#const, SymType::Const => IdentKind::Const, dim, dtype);
test_kind!(func, SymType::Func => IdentKind::Func, dim, dtype);
test_kind!(gen, SymType::Gen => IdentKind::Gen, dim, dtype);
test_kind!(lparam, SymType::Lparam => IdentKind::Lparam, dim, dtype);
test_kind!(param, SymType::Param => IdentKind::Param, dim, dtype);
test_kind!(rate, SymType::Rate => IdentKind::Rate, dtype);
test_kind!(tpl, SymType::Tpl => IdentKind::Tpl);
test_kind!(r#type, SymType::Type => IdentKind::Type, dtype);
test_kind!(maphead, SymType::MapHead => IdentKind::MapHead);
test_kind!(map, SymType::Map => IdentKind::Map);
test_kind!(maptail, SymType::MapTail => IdentKind::MapTail);
test_kind!(retmaphead, SymType::RetMapHead => IdentKind::RetMapHead);
test_kind!(retmap, SymType::RetMap => IdentKind::RetMap);
test_kind!(retmaptail, SymType::RetMapTail => IdentKind::RetMapTail);
test_kind!(meta, SymType::Meta => IdentKind::Meta);
test_kind!(worksheet, SymType::Worksheet => IdentKind::Worksheet);
#[test]
fn source_from_sym_attrs() {
let nsym: SymbolId = "name".intern();
let ssym: SymbolId = "src".intern();
let psym: SymbolId = "parent".intern();
let ysym: SymbolId = "yields".intern();
let fsym: SymbolId = "from".intern();
let attrs = SymAttrs {
pkg_name: Some(nsym),
src: Some(ssym),
generated: true,
parent: Some(psym),
yields: Some(ysym),
desc: Some("sym desc".into()),
from: Some(fsym),
virtual_: true,
override_: true,
..Default::default()
};
assert_eq!(
Source {
pkg_name: Some(nsym),
src: Some(ssym),
generated: attrs.generated,
parent: attrs.parent,
yields: attrs.yields,
desc: Some("sym desc".into()),
from: Some(fsym),
virtual_: true,
override_: true,
},
attrs.into(),
);
}