adds smoke tests to everything

adds deflated test examples
This commit is contained in:
Trevor Merritt 2025-05-28 11:32:09 -04:00
parent e45d269828
commit 6c902de16f
37 changed files with 185 additions and 82 deletions

View File

@ -10,6 +10,9 @@
<sourceFolder url="file://$MODULE_DIR$/gemmatelnet/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gemmautil/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/gemmautil/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gemmaegui/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gemmaimgui/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gemmatelnet/tests" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/target" />
</content>
<orderEntry type="inheritedJdk" />

1
Cargo.lock generated
View File

@ -1733,6 +1733,7 @@ dependencies = [
"chrono",
"clap",
"dimensioned",
"env_logger",
"flate2",
"hex",
"log",

View File

@ -25,3 +25,5 @@ eframe = { version = "0.29" }
# IMGUI
# EXPERIMENT
# Personal

View File

@ -16,3 +16,4 @@ serde_json.workspace = true
flate2 = "1.0"
clap = { version = "4.5.20", features = ["derive"] }
hex = "0.4.3"
env_logger = "0.10.2"

View File

@ -21,16 +21,18 @@
use std::fs;
use std::fs::File;
use clap::{Parser, Subcommand};
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::io::prelude::*;
use std::io::Read;
use std::io::Write;
use flate2::Compression;
use flate2::write::{GzEncoder, ZlibEncoder};
use flate2::write::{DeflateEncoder, GzEncoder, ZlibEncoder};
use gemma::constants::{TESTS_ROOT, TEST_ROM_ROOT};
use flate2::read::{DeflateDecoder, DeflateEncoder, GzDecoder};
use flate2::read::{DeflateDecoder};
use std::io::prelude::*;
use std::io;
use std::ptr::write;
use log::{debug, info};
#[derive(Parser)]
#[command(author, version, about = "Compress or decompress a string", long_about = None)]
@ -54,72 +56,63 @@ enum Commands {
}
}
fn compress_file(input_path: &PathBuf) {
let file = File::open(&input_path).unwrap();
let mut compressed_bytes= Vec::new();
let mut deflater = DeflateEncoder::new(file, Compression::fast());
deflater.read_to_end(&mut compressed_bytes).expect("Unable to write compressed data to buffer ");
let output_filename = format!("{}.deflated", input_path.display());
let output_file = File::create(&output_filename);
output_file.unwrap().write_all(&compressed_bytes).expect("Unable to write compressed version");
fn compress_file(input_path: &PathBuf) -> io::Result<()> {
let compressed_bytes= compress_file_to_array(input_path);
let output_filename = input_path.with_extension("deflated");
let mut output_file = File::create(&output_filename)?;
output_file.write_all(&compressed_bytes.unwrap())?;
Ok(())
}
fn decompress_file(input_path: &PathBuf) {
let file = File::open(&input_path).unwrap();
let mut uncompressed_bytes = Vec::new();
fn compress_file_to_array(input_path: &Path) -> Result<Vec<u8>, String> {
let mut file = File::open(input_path)
.map_err(|e| std::io::Error::new(e.kind(), format!("Unable to open input path [{}]: {}", input_path.display(), e)));
let mut inflater = DeflateDecoder::new(file);
inflater.read_to_end(&mut uncompressed_bytes).expect("Unable to inflate.");
let mut read_buffer = Vec::new();
let mut write_buffer = Vec::new();
file.unwrap().read_to_end(&mut read_buffer)
.map_err(|e| std::io::Error::new(e.kind(), format!("Unable to read input file [{}]: {}", input_path.display(), e)));
let target_file_name = format!("{}.inflated", input_path.display());
println!("Writing decompressed data to {}", target_file_name);
let mut encoder = DeflateEncoder::new(read_buffer, Compression::default());
encoder.write_all(&write_buffer)
.map_err(|e| std::io::Error::new(e.kind(), format!("Unable to compress data for [{}]: {}", input_path.display(), e)));
let mut target_file = File::create(&target_file_name)
.expect("Unable to create uncompressed output file");
target_file
.write_all(&uncompressed_bytes)
.expect("Unable to write decompressed file");
debug!("Compressed file from path: {}", input_path.display());
Ok(write_buffer)
}
// let decompressed_data = decompress_data(input_data);
// let mut target_file = File::create(&target_file_name).expect(format!("Unable to create uncompressed file -> {}", target_file_name.clone()).as_str());
//target_file.write_all(&decompressed_data).expect(format!("Unable to write uncompressed file -> {}", target_file_name).as_str());
//println!("Decompressed: {:?}", String::from_utf8_lossy(&decompressed_data));
fn decompress_file_to_array(input_path: &Path) -> Vec<u8> {
let file = File::open(input_path)
.map_err(|e| std::io::Error::new(e.kind(), format!("Unable to open input path [{}]: {}", input_path.display(), e)));
let mut decoder = DeflateDecoder::new(file.unwrap());
let mut return_vec = Vec::new();
decoder.read_to_end(&mut return_vec)
.map_err(|e| std::io::Error::new(e.kind(), format!("Unable to decompress data for [{}]: {}", input_path.display(), e)));
debug!("Decompressed file from path: {}", input_path.display());
return_vec
}
fn decompress_file(input_path: &PathBuf) -> io::Result<()> {
let decompressed_bytes = decompress_file_to_array(input_path);
let output_path = input_path.with_extension("inflated");
let mut output_file = File::create(&output_path)?;
output_file.write_all(&decompressed_bytes).expect(format!("Unable to write compressed data to [{}]", output_path.display()).as_str());
Ok(())
}
fn main() {
env_logger::init();
let cli = Cli::parse();
let raw_file = format!("{}/gemma/{}test_scroll_down_10_hd.asc", std::env::current_dir().unwrap().display(), TESTS_ROOT);
let compressed_file = format!("{}.deflated", &raw_file);
let uncompressed_file = format!("{}.inflated", &compressed_file);
println!("[ + ] Writing compressed file from {}", &raw_file);
compress_file(&raw_file.clone().into());
decompress_file(&compressed_file.into());
///////// COMPRESSION COMPLETE. TIME TO DECOMPRESS AND COMPARE
//
//
//
// match cli.command {
// Commands::Compress { input } => {
// let compressed = compress_string(&input);
// // Convert to hex format for easier readability in the terminal
// println!("Compressed (hex): {:?} / from {}b to {}b", hex::encode(compressed.clone()), input.len(), compressed.len());
// }
// Commands::Decompress { input } => {
// // Decode hex string back to bytes
// let compressed_bytes = hex::decode(input).expect("Invalid hex input");
// let decompressed = decompress_string(&compressed_bytes);
// println!("Decompressed: {}", decompressed);
// }
// Commands::DecompressFile { input } => {
// decompress_file(&input);
// }
// Commands::CompressFile { input } => {
// compress_file(&input);
// }
// }
match cli.command {
Commands::Compress { input } => {
compress_file(&input).expect(format!("Unable to compress {}", input.display()).as_str());
}
Commands::Decompress { input } => {
decompress_file(&input).expect(format!("Unable to decompress {}", input.display()).as_str());
}
}
}

View File

@ -1,4 +1,5 @@
use std::path::Path;
mod test_utils;
use std::path::{Path, PathBuf};
use std::time::Instant;
use gemma::chip8::computer::Chip8Computer;
use gemma::chip8::computer_manager::Chip8ComputerManager;
@ -6,19 +7,13 @@ use gemma::chip8::quirk_modes::QuirkMode;
use gemma::chip8::quirk_modes::QuirkMode::{Chip8, SChipModern, XOChip};
use gemma::chip8::registers::Chip8Registers;
use gemma::constants::{CHIP8_VIDEO_MEMORY, TESTS_ROOT};
use crate::test_utils::{load_compressed_result, load_result, load_rom};
#[test]
fn smoke() {
assert!(true)
}
fn load_result(to_load: &str) -> String {
std::fs::read_to_string(format!("../resources/test/{}", to_load)).unwrap()
}
fn load_rom(to_load: &str) -> Vec<u8> {
std::fs::read(format!("../resources/roms/{}", to_load)).unwrap()
}
#[test]
fn reset_clears_video() {
@ -88,6 +83,21 @@ fn level3_test() {
);
}
#[test]
fn level3_compressed_test() {
let mut x = Chip8Computer::new();
x.load_bytes_to_memory(0x200, &load_rom("3-corax+.ch8"));
for i in 0..0x180 {
x.step_system();
}
assert_eq!(
x.dump_video_to_string(),
load_compressed_result("gemma_integration.corax_plus.deflated")
);
}
#[test]
fn rps_test() {
let mut x = Chip8Computer::new();
@ -97,7 +107,7 @@ fn rps_test() {
}
assert_eq!(
x.dump_video_to_string(),
load_result("gemma_integration_rps_stage1.asc")
load_compressed_result("gemma_integration_rps_stage1")
);
x.keypad.push_key(0x01);
for _ in 0..0x200 {
@ -105,7 +115,7 @@ fn rps_test() {
}
assert_eq!(
x.dump_video_to_string(),
load_result("gemma_integration_rps_stage2.asc")
load_compressed_result("gemma_integration_rps_stage2")
);
}
@ -176,11 +186,11 @@ fn quirks_mode_test() {
#[test]
fn load_rom_allows_starting() {
let mut new_manager = Chip8ComputerManager::default();
assert_eq!(new_manager.core_should_run, false);
assert!(!new_manager.core_should_run);
let p = format!("{}/../resources/test/roms/1-chip8-logo.ch8" , std::env::current_dir().unwrap().display());
let full_path = Path::new(p.as_str());
new_manager.load_new_program_from_disk_to_system_memory(full_path);
assert_eq!(new_manager.core_should_run, true)
assert!(new_manager.core_should_run)
}
#[test]
@ -189,5 +199,20 @@ fn reset_clears_run_state() {
let p = format!("{}/../resources/test/roms/1-chip8-logo.ch8", std::env::current_dir().unwrap().display());
new_manager.load_new_program_from_disk_to_system_memory(Path::new(p.as_str()));
new_manager.reset(QuirkMode::Chip8);
assert_eq!(new_manager.core_should_run, false);
assert!(!new_manager.core_should_run);
}
#[test]
fn tick_when_ready() {
let mut new_manager = Chip8ComputerManager::default();
new_manager.load_new_program_from_disk_to_system_memory(Path::new(
format!("{}/../resources/test/roms/1-chip8-logo.ch8", std::env::current_dir().unwrap().display()).as_str()));
assert!(new_manager.core_should_run);
}
#[test]
fn tick_when_not_ready() {}
#[test]
fn tick_one_step_only() {}

View File

@ -0,0 +1,18 @@
use crate::test_utils::{compress_string, decompress_to_string};
mod test_utils;
#[test]
fn smoke() {
assert!(true)
}
#[test]
fn round_trip() {
let text_to_process = "The quick brown fox jumps over the lazy dog.";
let compressed = compress_string(text_to_process);
let decompressed = decompress_to_string(&compressed).unwrap();
assert_eq!(text_to_process, decompressed);
}

52
gemma/tests/test_utils.rs Normal file
View File

@ -0,0 +1,52 @@
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use flate2::Compression;
use flate2::read::DeflateDecoder;
use flate2::write::{DeflateEncoder};
use log::debug;
const TEST_OUTPUT_SAMPLE_DIR: &str = "../resources/test/";
pub fn compress_string(input: &str) -> Vec<u8> {
let mut encoder = DeflateEncoder::new(Vec::new(), Compression::default());
encoder.write_all(input.as_bytes()).expect("Failed to write data");
encoder.finish().expect("Failed to finish compression")
}
pub fn decompress_to_string(compressed_data: &[u8]) -> Result<String, std::io::Error> {
let mut decoder = DeflateDecoder::new(compressed_data);
let mut decompressed = String::new();
decoder.read_to_string(&mut decompressed)?;
Ok(decompressed)
}
/// Read a compressed test result and return the expected result
/// as a string
pub fn read_compressed_test_result(suffix: &str) -> String {
let full_path = std::env::current_dir().unwrap().display().to_string() + "/" + &*TEST_OUTPUT_SAMPLE_DIR.to_owned() + suffix + ".deflated";
println!("LOADING {}", full_path);
let mut compressed_file = File::open(full_path).expect(format!("Unable to load test result [{}]", suffix).as_str());
let mut compressed_data = Vec::new();
compressed_file.read_to_end(&mut compressed_data).expect("Unable to compress data");
decompress_to_string(&compressed_data).unwrap()
}
pub fn load_compressed_result(suffix: &str) -> String {
read_compressed_test_result(suffix)
}
pub fn read_test_result(suffix: &str) -> String {
std::fs::read_to_string(TEST_OUTPUT_SAMPLE_DIR.to_owned() + suffix).unwrap()
}
pub fn load_result(to_load: &str) -> String {
std::fs::read_to_string(format!("../resources/test/{}", to_load)).unwrap()
}
pub fn load_rom(to_load: &str) -> Vec<u8> {
std::fs::read(format!("../resources/roms/{}", to_load)).unwrap()
}

View File

@ -18,14 +18,9 @@ use log::debug;
use rand::random;
use serde::Serialize;
use gemma::chip8::computer_manager::Chip8ComputerManager;
use crate::test_utils::read_test_result;
const TEST_OUTPUT_SAMPLE_DIR: &str = "../resources/test/";
fn read_test_result(suffix: &str) -> String {
println!("SITTING IN {:?}", std::env::current_dir());
println!("ATTEMPT TO READ RESULT {suffix}");
std::fs::read_to_string(TEST_OUTPUT_SAMPLE_DIR.to_owned() + suffix).unwrap()
}
mod test_utils;
#[test]
fn smoke() {

View File

@ -21,7 +21,6 @@ fn byte_to_bools() {
}
}
#[test]
fn bools_to_byte() {
let data_set: BTreeMap<u8, [bool; 8]> = BTreeMap::from(

View File

@ -149,7 +149,7 @@ fn main() -> eframe::Result {
});
// run our target number of ticks in the amount of available time.
let time_consumed = Instant::now().duration_since(frame_start_time).as_millis();
// let time_consumed = Instant::now().duration_since(frame_start_time).as_millis();
let mut num_ticks = 0;
while num_ticks < 1000 {
computer.tick();

4
gemmaegui/tests/smoke.rs Normal file
View File

@ -0,0 +1,4 @@
#[test]
fn smoke() {
assert!(true)
}

View File

@ -0,0 +1,4 @@
#[test]
fn smoke() {
assert!(true)
}

View File

@ -0,0 +1,4 @@
#[test]
fn smoke() {
assert!(true)
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
í”M
Â0…×Î)æŽÕú“­+Dªt_T ­c¡…wxÓz€ë !¼@xßÌåÑ´•å¤}.²Ê;:µ5ïû¼rÞ°Pâî¥ÿ¸·§´ ÷N„eò kúÙèD‡Ÿ­Èì¼e$BײŽâx.ttý+³† DX"a… 6ØbTÁ ˆÒҺƌu„RþÞjÀ¬hC)Ê<>r0$  )è<Ð

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File