1#[cfg(test)]
2mod tests {
3 use crate::op_code::Opcode::{OpAdd, OpClosure, OpConst, OpGetLocal};
4 use crate::op_code::*;
5 use std::collections::HashSet;
6 use strum::EnumCount;
7
8 #[test]
9 fn test_make() {
10 struct Test {
11 op: Opcode,
12 operands: Vec<usize>,
13 expected: Vec<u8>,
14 }
15
16 let tests = vec![
17 Test {
18 op: Opcode::OpConst,
19 operands: vec![65534],
20 expected: vec![OpConst as u8, 255, 254],
21 },
22 Test { op: Opcode::OpAdd, operands: vec![], expected: vec![OpAdd as u8] },
23 Test {
24 op: Opcode::OpGetLocal,
25 operands: vec![255],
26 expected: vec![OpGetLocal as u8, 255],
27 },
28 ];
29
30 for t in tests {
31 let ins = make_instructions(t.op, &t.operands);
32 assert_eq!(ins.data, t.expected)
33 }
34 }
35
36 #[test]
37 fn test_read_operands() {
38 struct Test {
39 op: Opcode,
40 operands: Vec<usize>,
41 bytes_read: usize,
42 }
43
44 let tests = vec![
45 Test { op: Opcode::OpConst, operands: vec![65534], bytes_read: 2 },
46 Test { op: Opcode::OpConst, operands: vec![255], bytes_read: 2 },
47 ];
48
49 for t in tests {
50 let ins = make_instructions(t.op, &t.operands);
51 let (operands_read, n) = read_operands(DEFINITIONS.get(&t.op).unwrap(), &ins.data[1..]);
52 assert_eq!(operands_read, t.operands);
53 assert_eq!(n, t.bytes_read);
54 }
55 }
56 #[test]
57 fn test_instructions_legal() {
58 let opcode_count = Opcode::COUNT;
59 let keys_count = DEFINITIONS.keys().count();
60 let op_keys = DEFINITIONS
61 .values()
62 .map(|d| d.name.to_string())
63 .collect::<HashSet<String>>();
64 assert_eq!(opcode_count, keys_count);
65 assert_eq!(opcode_count, op_keys.len());
67 }
68
69 #[test]
70 fn test_instructions_string() {
71 let ins = vec![
72 make_instructions(OpAdd, &vec![]),
73 make_instructions(OpGetLocal, &vec![1]),
74 make_instructions(OpConst, &vec![2]),
75 make_instructions(OpConst, &vec![65535]),
76 make_instructions(OpClosure, &vec![65535, 255])
77 ];
78
79 let expected = "0000 OpAdd\n\
80 0001 OpGetLocal 1\n\
81 0003 OpConst 2\n\
82 0006 OpConst 65535\n\
83 0009 OpClosure 65535 255\n";
84 let merged_ins = ins
87 .iter()
88 .fold(vec![], |sum, i| [sum.as_slice(), i.data.as_slice()].concat());
89
90 let concatted = Instructions { data: merged_ins }.string();
91
92 assert_eq!(concatted, expected);
93 }
94}