mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-17 06:47:49 +00:00
Create new post about unit testing
This commit is contained in:
10
src/main.rs
10
src/main.rs
@@ -1,18 +1,25 @@
|
||||
#![feature(lang_items)] // required for defining the panic handler
|
||||
#![feature(const_fn)] // allow declaring functions as const
|
||||
#![no_std] // don't link the Rust standard library
|
||||
#![no_main] // disable all Rust-level entry points
|
||||
#![cfg_attr(not(test), no_main)] // disable all Rust-level entry points
|
||||
#![cfg_attr(test, allow(dead_code, unused_macros))] // allow unused code in test mode
|
||||
|
||||
extern crate spin;
|
||||
extern crate volatile;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate array_init;
|
||||
#[cfg(test)]
|
||||
extern crate std;
|
||||
|
||||
#[macro_use]
|
||||
mod vga_buffer;
|
||||
|
||||
/// This function is the entry point, since the linker looks for a function
|
||||
/// named `_start_` by default.
|
||||
#[cfg(not(test))]
|
||||
#[no_mangle] // don't mangle the name of this function
|
||||
pub extern "C" fn _start() -> ! {
|
||||
println!("Hello World{}", "!");
|
||||
@@ -21,6 +28,7 @@ pub extern "C" fn _start() -> ! {
|
||||
}
|
||||
|
||||
/// This function is called on panic.
|
||||
#[cfg(not(test))]
|
||||
#[lang = "panic_fmt"]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_begin_panic(
|
||||
|
||||
@@ -15,7 +15,7 @@ lazy_static! {
|
||||
|
||||
/// The standard color palette in VGA text mode.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum Color {
|
||||
Black = 0,
|
||||
@@ -37,7 +37,7 @@ pub enum Color {
|
||||
}
|
||||
|
||||
/// A combination of a foreground and a background color.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
struct ColorCode(u8);
|
||||
|
||||
impl ColorCode {
|
||||
@@ -48,7 +48,7 @@ impl ColorCode {
|
||||
}
|
||||
|
||||
/// A screen character in the VGA text buffer, consisting of an ASCII character and a `ColorCode`.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(C)]
|
||||
struct ScreenChar {
|
||||
ascii_character: u8,
|
||||
@@ -113,7 +113,6 @@ impl Writer {
|
||||
// not part of printable ASCII range
|
||||
_ => self.write_byte(0xfe),
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,3 +164,86 @@ pub fn print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
WRITER.lock().write_fmt(args).unwrap();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
fn construct_writer() -> Writer {
|
||||
use std::boxed::Box;
|
||||
|
||||
let buffer = construct_buffer();
|
||||
Writer {
|
||||
column_position: 0,
|
||||
color_code: ColorCode::new(Color::Blue, Color::Magenta),
|
||||
buffer: Box::leak(Box::new(buffer)),
|
||||
}
|
||||
}
|
||||
|
||||
fn construct_buffer() -> Buffer {
|
||||
use array_init::array_init;
|
||||
|
||||
Buffer {
|
||||
chars: array_init(|_| array_init(|_| Volatile::new(empty_char()))),
|
||||
}
|
||||
}
|
||||
|
||||
fn empty_char() -> ScreenChar {
|
||||
ScreenChar {
|
||||
ascii_character: b' ',
|
||||
color_code: ColorCode::new(Color::Green, Color::Brown),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_byte() {
|
||||
let mut writer = construct_writer();
|
||||
writer.write_byte(b'X');
|
||||
writer.write_byte(b'Y');
|
||||
|
||||
for (i, row) in writer.buffer.chars.iter().enumerate() {
|
||||
for (j, screen_char) in row.iter().enumerate() {
|
||||
let screen_char = screen_char.read();
|
||||
if i == BUFFER_HEIGHT - 1 && j == 0 {
|
||||
assert_eq!(screen_char.ascii_character, b'X');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else if i == BUFFER_HEIGHT - 1 && j == 1 {
|
||||
assert_eq!(screen_char.ascii_character, b'Y');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else {
|
||||
assert_eq!(screen_char, empty_char());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_formatted() {
|
||||
use core::fmt::Write;
|
||||
|
||||
let mut writer = construct_writer();
|
||||
writeln!(&mut writer, "a").unwrap();
|
||||
writeln!(&mut writer, "b{}", "c").unwrap();
|
||||
|
||||
for (i, row) in writer.buffer.chars.iter().enumerate() {
|
||||
for (j, screen_char) in row.iter().enumerate() {
|
||||
let screen_char = screen_char.read();
|
||||
if i == BUFFER_HEIGHT - 3 && j == 0 {
|
||||
assert_eq!(screen_char.ascii_character, b'a');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else if i == BUFFER_HEIGHT - 2 && j == 0 {
|
||||
assert_eq!(screen_char.ascii_character, b'b');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else if i == BUFFER_HEIGHT - 2 && j == 1 {
|
||||
assert_eq!(screen_char.ascii_character, b'c');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else if i >= BUFFER_HEIGHT - 2 {
|
||||
assert_eq!(screen_char.ascii_character, b' ');
|
||||
assert_eq!(screen_char.color_code, writer.color_code);
|
||||
} else {
|
||||
assert_eq!(screen_char, empty_char());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user