use crate::{Convention, DataType, OpSignature, OpSpec};
#[cfg(test)]
mod tests {
use super::*;
use super::{cpu_fn, example_table, scan_dfa_cpu, validate, DfaSpec, BYTE_CLASSES};
fn make_spec(table: &super::OwnedExampleTable) -> DfaSpec<'_> {
DfaSpec {
transitions: &table.transitions,
state_count: table.state_count,
accept_states: &table.accept_states,
pattern_lengths: &table.pattern_lengths,
}
}
#[test]
fn scans_ab_and_cd() {
let table = example_table();
let spec = make_spec(&table);
let matches = scan_dfa_cpu(&spec, b"xxabxxcdxx").expect("valid spec");
assert_eq!(matches.len(), 2);
assert_eq!(
(matches[0].pattern_id, matches[0].start, matches[0].end),
(0, 2, 4)
);
assert_eq!(
(matches[1].pattern_id, matches[1].start, matches[1].end),
(1, 6, 8)
);
}
#[test]
fn empty_input_returns_no_matches() {
let table = example_table();
let spec = make_spec(&table);
let matches = scan_dfa_cpu(&spec, b"").expect("valid spec");
assert!(matches.is_empty());
}
#[test]
fn no_match_in_input() {
let table = example_table();
let spec = make_spec(&table);
let matches = scan_dfa_cpu(&spec, b"xxxxxxxxxxx").expect("valid spec");
assert!(matches.is_empty());
}
#[test]
fn validate_zero_states() {
let spec = DfaSpec {
transitions: &[],
state_count: 0,
accept_states: &[],
pattern_lengths: &[],
};
assert!(validate(&spec).is_err());
}
#[test]
fn validate_wrong_transition_count() {
let spec = DfaSpec {
transitions: &[0; 100], state_count: 1,
accept_states: &[],
pattern_lengths: &[],
};
assert!(validate(&spec).is_err());
}
#[test]
fn validate_invalid_transition_target() {
let mut transitions = vec![0u32; BYTE_CLASSES];
transitions[0] = 5; let spec = DfaSpec {
transitions: &transitions,
state_count: 1,
accept_states: &[],
pattern_lengths: &[],
};
assert!(validate(&spec).is_err());
}
#[test]
fn validate_invalid_accept_state() {
let transitions = vec![0u32; BYTE_CLASSES];
let spec = DfaSpec {
transitions: &transitions,
state_count: 1,
accept_states: &[(5, 0)], pattern_lengths: &[1],
};
assert!(validate(&spec).is_err());
}
#[test]
fn validate_duplicate_accept_state() {
let transitions = vec![0u32; 2 * BYTE_CLASSES];
let spec = DfaSpec {
transitions: &transitions,
state_count: 2,
accept_states: &[(1, 0), (1, 1)], pattern_lengths: &[1, 1],
};
assert!(validate(&spec).is_err());
}
#[test]
fn cpu_fn_empty_input_no_panic() {
let result = cpu_fn(b"");
assert_eq!(
result,
vec![0, 0, 0, 0],
"empty input should produce 0 matches as u32"
);
}
#[test]
fn cpu_fn_match_returns_u32_count() {
let result = cpu_fn(b"ab");
assert_eq!(
result.len(),
4,
"match output should be exactly 4 bytes (u32 count)"
);
let count = u32::from_le_bytes([result[0], result[1], result[2], result[3]]);
assert_eq!(count, 1, "input 'ab' should produce exactly 1 match");
}
}