Create new post about unit testing

This commit is contained in:
Philipp Oppermann
2018-04-25 10:07:53 +02:00
parent d7efdf013a
commit 44ffa1d046
4 changed files with 493 additions and 5 deletions

View File

@@ -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(

View File

@@ -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());
}
}
}
}
}