Skip to content

Commit 9fb1a6c

Browse files
1BADragonCedarMatt
andauthored
More testing and default functions (#47)
* More coverage * wip * Add a ton of string manip functions * Ready * Bump package version --------- Co-authored-by: matt <[email protected]>
1 parent 66a1e9e commit 9fb1a6c

27 files changed

+695
-44
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ default-members = ["rscel"]
44
resolver = "2"
55

66
[workspace.package]
7-
version = "1.0.5"
7+
version = "1.0.6"
88
edition = "2021"
99
description = "Cel interpreter in rust"
1010
license = "MIT"

python/src/py_cel_program.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ impl PyCelProgram {
6161
}
6262
}
6363

64-
fn serialize_to_bincode(slf: PyRefMut<'_, PyCelProgram>) -> PyResult<Cow<[u8]>> {
64+
fn serialize_to_bincode(slf: PyRefMut<'_, PyCelProgram>) -> PyResult<Cow<'_, [u8]>> {
6565
if let Some(program) = &slf.program {
6666
match bincode::serialize(program) {
6767
Ok(b) => Ok(Cow::Owned(b)),

rscel-macro/src/types/dispatch_arg_type.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub enum DispatchArgType {
1414
Timestamp,
1515
Duration,
1616
CelResult,
17+
CelValue,
1718
}
1819

1920
impl DispatchArgType {
@@ -52,6 +53,7 @@ impl DispatchArgType {
5253
"Duration" => DispatchArgType::Duration,
5354
"CelResult" => DispatchArgType::CelResult,
5455
"CelBytes" => DispatchArgType::Bytes,
56+
"CelValue" => DispatchArgType::CelValue,
5557
other => panic!("Unknown type: {}", other),
5658
},
5759
None => panic!("No type info"),
@@ -74,6 +76,7 @@ impl DispatchArgType {
7476
DispatchArgType::Timestamp => 't',
7577
DispatchArgType::Duration => 'y',
7678
DispatchArgType::CelResult => 'r',
79+
DispatchArgType::CelValue => 'z',
7780
}
7881
}
7982

rscel/src/compiler/ast_node.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,40 @@ impl<T> AstNode<T> {
3434
&self.node
3535
}
3636
}
37+
38+
#[cfg(test)]
39+
mod test {
40+
use super::AstNode;
41+
use crate::{SourceLocation, SourceRange};
42+
43+
#[derive(Debug, PartialEq)]
44+
struct FakeNode {
45+
v: u32,
46+
}
47+
48+
#[test]
49+
fn basic() {
50+
let a = AstNode::new(
51+
FakeNode { v: 42 },
52+
SourceRange::new(SourceLocation::new(0, 0), SourceLocation::new(0, 20)),
53+
);
54+
55+
assert_eq!(a.start(), SourceLocation::new(0, 0));
56+
assert_eq!(a.end(), SourceLocation::new(0, 20));
57+
58+
assert_eq!(
59+
a.range(),
60+
SourceRange::new(SourceLocation::new(0, 0), SourceLocation::new(0, 20))
61+
);
62+
63+
assert_eq!(*a.node(), FakeNode { v: 42 });
64+
65+
let (node, range) = a.into_parts();
66+
assert_eq!(
67+
range,
68+
SourceRange::new(SourceLocation::new(0, 0), SourceLocation::new(0, 20))
69+
);
70+
71+
assert_eq!(node.v, 42);
72+
}
73+
}

rscel/src/compiler/compiled_prog.rs

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,3 +264,244 @@ impl NodeValue {
264264
}
265265
}
266266
}
267+
268+
#[cfg(test)]
269+
mod test {
270+
271+
use crate::{
272+
compiler::compiled_prog::PreResolvedCodePoint, types::CelByteCode, ByteCode, CelValue,
273+
ProgramDetails,
274+
};
275+
276+
use super::{CompiledProg, NodeValue};
277+
278+
mod helpers {
279+
use super::CelValue;
280+
use std::ops::Add as _;
281+
282+
pub fn add_values(values: Vec<CelValue>) -> CelValue {
283+
values.into_iter().reduce(|v1, v2| v1 + v2).unwrap()
284+
}
285+
286+
pub fn add_2(val1: &CelValue, val2: &CelValue) -> Option<CelValue> {
287+
Some(val1.clone().add(val2.clone()))
288+
}
289+
}
290+
291+
#[test]
292+
fn node_basic() {
293+
let a = NodeValue::ConstExpr(CelValue::Int(32));
294+
let b = NodeValue::Bytecode(
295+
[
296+
ByteCode::Push(0.into()),
297+
ByteCode::Push(3.into()),
298+
ByteCode::Mul,
299+
]
300+
.into_iter()
301+
.collect(),
302+
);
303+
304+
assert!(a.is_const());
305+
assert!(!b.is_const());
306+
307+
let a_bc = a.into_bytecode();
308+
assert_eq!(a_bc.len(), 1);
309+
assert_eq!(
310+
a_bc[0],
311+
PreResolvedCodePoint::Bytecode(ByteCode::Push(32.into()))
312+
);
313+
}
314+
315+
#[test]
316+
fn compprog_basic() {
317+
let details = ProgramDetails::new();
318+
let node = NodeValue::ConstExpr(0.into());
319+
320+
fn is_empty(prog: CompiledProg) -> bool {
321+
return prog.is_const() || prog.bytecode_len() == 0;
322+
}
323+
324+
// test the basic contructors
325+
assert!(is_empty(CompiledProg::new(node.clone(), details.clone())));
326+
assert!(is_empty(CompiledProg::empty()));
327+
assert!(is_empty(CompiledProg::from_node(CompiledProg::empty())));
328+
assert!(is_empty(CompiledProg::with_bytecode(CelByteCode::new())));
329+
assert!(is_empty(CompiledProg::with_code_points(Vec::new())));
330+
331+
assert!(CompiledProg::empty().details().params().is_empty());
332+
let mut const_prog = CompiledProg::with_const(42.into());
333+
assert!(const_prog.is_const());
334+
assert!(const_prog.bytecode_len() == 1);
335+
336+
const_prog.append_if_bytecode([PreResolvedCodePoint::Bytecode(ByteCode::Dup)]);
337+
assert!(const_prog.is_const());
338+
assert!(const_prog.bytecode_len() == 1);
339+
340+
let (node, details) = const_prog.into_parts();
341+
342+
if let NodeValue::ConstExpr(inner) = node {
343+
assert_eq!(inner, 42.into());
344+
} else {
345+
assert!(false);
346+
}
347+
348+
assert!(details.params().is_empty());
349+
350+
let mut bc_prog = CompiledProg::empty();
351+
assert!(!bc_prog.is_const());
352+
assert!(bc_prog.bytecode_len() == 0);
353+
bc_prog.append_if_bytecode([PreResolvedCodePoint::Bytecode(ByteCode::Dup)]);
354+
assert!(bc_prog.bytecode_len() == 1);
355+
}
356+
357+
#[test]
358+
fn from_child_2_nonconst() {
359+
let c1 = CompiledProg::with_bytecode([ByteCode::Push(2.into())].into_iter().collect());
360+
let c2 = CompiledProg::with_bytecode([ByteCode::Push(5.into())].into_iter().collect());
361+
362+
let c3 = CompiledProg::from_children2_w_bytecode_cannone(
363+
c1,
364+
c2,
365+
vec![ByteCode::Add],
366+
helpers::add_2,
367+
);
368+
369+
assert!(!c3.is_const());
370+
assert_eq!(c3.bytecode_len(), 3);
371+
372+
assert_eq!(
373+
c3.into_unresolved_bytecode().resolve(),
374+
[
375+
ByteCode::Push(2.into()),
376+
ByteCode::Push(5.into()),
377+
ByteCode::Add
378+
]
379+
.into_iter()
380+
.collect()
381+
)
382+
}
383+
384+
#[test]
385+
fn from_child_2_const() {
386+
let c1 = CompiledProg::with_const(2.into());
387+
let c2 = CompiledProg::with_const(5.into());
388+
389+
let c3 = CompiledProg::from_children2_w_bytecode_cannone(
390+
c1.clone(),
391+
c2.clone(),
392+
vec![ByteCode::Add],
393+
helpers::add_2,
394+
);
395+
396+
assert!(c3.is_const());
397+
assert_eq!(c3.clone().const_val(), 7.into());
398+
assert_eq!(
399+
c3.into_unresolved_bytecode().resolve(),
400+
[ByteCode::Push(7.into()),].into_iter().collect()
401+
);
402+
403+
let c4 = CompiledProg::from_children2_w_bytecode_cannone(
404+
c1.clone(),
405+
c2.clone(),
406+
vec![ByteCode::Add],
407+
|_v1, _v2| None,
408+
);
409+
410+
assert!(!c4.is_const());
411+
assert_eq!(c4.bytecode_len(), 3);
412+
assert_eq!(
413+
c4.into_unresolved_bytecode().resolve(),
414+
[
415+
ByteCode::Push(2.into()),
416+
ByteCode::Push(5.into()),
417+
ByteCode::Add
418+
]
419+
.into_iter()
420+
.collect()
421+
)
422+
}
423+
424+
#[test]
425+
fn from_children_w_bytecode_nonconst() {
426+
let c1 = CompiledProg::with_bytecode([ByteCode::Push(2.into())].into_iter().collect());
427+
let c2 = CompiledProg::with_bytecode([ByteCode::Push(5.into())].into_iter().collect());
428+
429+
let c3 = CompiledProg::from_children_w_bytecode(
430+
vec![c1, c2],
431+
vec![ByteCode::Add],
432+
helpers::add_values,
433+
);
434+
435+
assert!(!c3.is_const());
436+
assert_eq!(c3.bytecode_len(), 3);
437+
438+
assert_eq!(
439+
c3.into_unresolved_bytecode().resolve(),
440+
[
441+
ByteCode::Push(2.into()),
442+
ByteCode::Push(5.into()),
443+
ByteCode::Add
444+
]
445+
.into_iter()
446+
.collect()
447+
)
448+
}
449+
450+
#[test]
451+
fn from_children_w_bytecode_const() {
452+
let c1 = CompiledProg::with_const(2.into());
453+
let c2 = CompiledProg::with_const(5.into());
454+
455+
let c3 = CompiledProg::from_children_w_bytecode(
456+
vec![c1, c2],
457+
vec![ByteCode::Add],
458+
helpers::add_values,
459+
);
460+
461+
assert!(c3.is_const());
462+
assert_eq!(c3.clone().const_val(), 7.into());
463+
assert_eq!(
464+
c3.into_unresolved_bytecode().resolve(),
465+
[ByteCode::Push(7.into()),].into_iter().collect()
466+
);
467+
}
468+
469+
#[test]
470+
fn consume_child() {
471+
let c = CompiledProg::with_const(5.into());
472+
473+
let p = CompiledProg::empty();
474+
475+
let r = p.consume_child(c);
476+
477+
assert!(!r.is_const());
478+
assert_eq!(r.bytecode_len(), 1)
479+
}
480+
481+
#[test]
482+
fn program() {
483+
let p = CompiledProg::with_bytecode(
484+
[
485+
ByteCode::Push(CelValue::from_ident("foo")),
486+
ByteCode::Push(4.into()),
487+
ByteCode::Mul,
488+
]
489+
.into_iter()
490+
.collect(),
491+
)
492+
.add_ident("foo")
493+
.into_program("foo * 4".to_owned());
494+
495+
assert_eq!(p.params(), vec!["foo"]);
496+
assert_eq!(
497+
p.bytecode(),
498+
&([
499+
ByteCode::Push(CelValue::from_ident("foo")),
500+
ByteCode::Push(4.into()),
501+
ByteCode::Mul
502+
]
503+
.into_iter()
504+
.collect::<CelByteCode>())
505+
);
506+
}
507+
}

0 commit comments

Comments
 (0)