use vyre::ir::{self, DataType};
use vyre::lower::wgsl;
use vyre::ops::string::tokenize_gpu;
use vyre::ops::{AlgebraicLaw, Category, Compose, OpSpec};
fn assert_category_a(spec: &OpSpec) {
assert!(matches!(spec.category(), Category::A));
assert!(matches!(spec.compose(), Compose::Composition(_)));
let program = spec
.program()
.expect("Category A specs must build programs");
assert!(
!program.entry().is_empty(),
"{} must not return an empty program",
spec.id()
);
}
#[test]
fn spec_is_category_a_composition() {
assert_category_a(&tokenize_gpu::Tokenize::SPEC);
}
#[test]
fn spec_declares_correct_types() {
assert_eq!(tokenize_gpu::Tokenize::SPEC.inputs(), &[DataType::Bytes]);
assert_eq!(tokenize_gpu::Tokenize::SPEC.outputs(), &[DataType::U32]);
}
#[test]
fn spec_declares_expected_laws() {
assert!(tokenize_gpu::Tokenize::SPEC
.laws()
.contains(&AlgebraicLaw::Bounded { lo: 0, hi: 7 }));
assert!(!tokenize_gpu::Tokenize::SPEC.inlinable());
}
#[test]
fn program_lowers_to_wgsl() {
let program = tokenize_gpu::Tokenize::SPEC
.program()
.expect("program must exist");
let shader = wgsl::lower(&program).unwrap_or_else(|e| panic!("lowering failed: {e}"));
assert!(shader.contains("@compute"));
assert!(shader.contains("source"));
assert!(shader.contains("tokens"));
}
#[test]
fn tokens_buffer_is_marked_output() {
let program = tokenize_gpu::Tokenize::program();
let tokens_buf = program.buffer("tokens").expect("tokens buffer must exist");
assert!(tokens_buf.is_output());
}
#[test]
fn op_is_registered_as_non_inlinable() {
let program = ir::Program::new(
vec![],
[1, 1, 1],
vec![ir::Node::let_bind(
"x",
ir::Expr::call("string.tokenize_gpu", vec![ir::Expr::u32(0)]),
)],
);
let err = vyre::ir::inline_calls(&program).expect_err("tokenize_gpu must not inline");
assert!(matches!(err, vyre::error::Error::InlineNonInlinable { .. }));
}
#[test]
fn host_helpers_filter_matches_by_token() {
use vyre::ir::engine::token_match_filter::{filter_matches_by_token, TokenType};
let tokens = [
TokenType::Identifier, TokenType::Operator, TokenType::String, TokenType::String, TokenType::Whitespace, ];
let matches = vec![
vyre::Match::new(0, 0, 1), vyre::Match::new(0, 1, 2), vyre::Match::new(0, 2, 4), vyre::Match::new(0, 4, 5), ];
let allowed = &[
TokenType::Identifier,
TokenType::Operator,
TokenType::String,
];
let filtered = filter_matches_by_token(&tokens, &matches, allowed);
assert_eq!(filtered.len(), 3);
assert_eq!(filtered[0].start, 0);
assert_eq!(filtered[1].start, 1);
assert_eq!(filtered[2].start, 2);
}
#[test]
fn host_helpers_filter_code_matches_excludes_comments_and_whitespace() {
use vyre::ir::engine::token_match_filter::{filter_code_matches, TokenType};
let tokens = [
TokenType::Identifier, TokenType::Whitespace, TokenType::Comment, TokenType::Number, ];
let matches = vec![
vyre::Match::new(0, 0, 1), vyre::Match::new(0, 1, 2), vyre::Match::new(0, 2, 3), vyre::Match::new(0, 3, 4), ];
let filtered = filter_code_matches(&tokens, &matches);
assert_eq!(filtered.len(), 2);
assert_eq!(filtered[0].start, 0);
assert_eq!(filtered[1].start, 3);
}