summaryrefslogtreecommitdiffstats
path: root/src/output
diff options
context:
space:
mode:
authorBen S <ogham@bsago.me>2015-05-16 21:02:28 +0100
committerBen S <ogham@bsago.me>2015-05-16 21:02:28 +0100
commit50442a0bfeb3b5b2f5a2d2700546b81621f9850f (patch)
treefafd744194caf6548bc9b617b786011cba925853 /src/output
parent8e7efed3f5ca66b0a92d13865f01d003bdadd918 (diff)
Generify Table to be used in tests once again
Finally! The benefit of having all the field-rendering code (in details.rs) separate from the value-getting code (in file.rs) is that rendering them can be tested again.
Diffstat (limited to 'src/output')
-rw-r--r--src/output/details.rs197
1 files changed, 191 insertions, 6 deletions
diff --git a/src/output/details.rs b/src/output/details.rs
index dff41a4..c784070 100644
--- a/src/output/details.rs
+++ b/src/output/details.rs
@@ -5,7 +5,9 @@ use dir::Dir;
use file::File;
use file::fields as f;
use options::{Columns, FileFilter, RecurseOptions, SizeFormat};
+
use users::{OSUsers, Users};
+use users::mock::MockUsers;
use super::filename;
@@ -29,7 +31,7 @@ use datetime::format::{DateFormat};
///
/// Almost all the heavy lifting is done in a Table object, which handles the
/// columns for each row.
-#[derive(PartialEq, Debug, Copy, Clone)]
+#[derive(PartialEq, Debug, Copy, Clone, Default)]
pub struct Details {
/// A Columns object that says which columns should be included in the
@@ -67,7 +69,7 @@ impl Details {
/// Adds files to the table - recursively, if the `recurse` option
/// is present.
- fn add_files_to_table(&self, table: &mut Table, src: &[File], depth: usize) {
+ fn add_files_to_table<U: Users>(&self, table: &mut Table<U>, src: &[File], depth: usize) {
for (index, file) in src.iter().enumerate() {
table.add_file(file, depth, index == src.len() - 1);
@@ -120,22 +122,36 @@ struct Row {
/// A **Table** object gets built up by the view as it lists files and
/// directories.
-struct Table {
+pub struct Table<U> {
columns: Vec<Column>,
rows: Vec<Row>,
time: locale::Time,
numeric: locale::Numeric,
- users: OSUsers,
+ users: U,
colours: Colours,
current_year: i64,
}
-impl Table {
+impl Default for Table<MockUsers> {
+ fn default() -> Table<MockUsers> {
+ Table {
+ columns: Columns::default().for_dir(None),
+ rows: Vec::new(),
+ time: locale::Time::english(),
+ numeric: locale::Numeric::english(),
+ users: MockUsers::with_current_uid(0),
+ colours: Colours::default(),
+ current_year: 1234,
+ }
+ }
+}
+
+impl Table<OSUsers> {
/// Create a new, empty Table object, setting the caching fields to their
/// empty states.
- fn with_options(colours: Colours, columns: Vec<Column>) -> Table {
+ fn with_options(colours: Colours, columns: Vec<Column>) -> Table<OSUsers> {
Table {
columns: columns,
rows: Vec::new(),
@@ -147,6 +163,9 @@ impl Table {
current_year: LocalDateTime::now().year(),
}
}
+}
+
+impl<U> Table<U> where U: Users {
/// Add a dummy "header" row to the table, which contains the names of all
/// the columns, underlined. This has dummy data for the cases that aren't
@@ -429,3 +448,169 @@ impl TreePart {
}
}
}
+
+
+#[cfg(test)]
+pub mod test {
+ pub use super::Table;
+ pub use file::File;
+ pub use file::fields as f;
+
+ pub use column::{Cell, Column};
+
+ pub use users::{User, Group, uid_t, gid_t};
+ pub use users::mock::MockUsers;
+
+ pub use ansi_term::Style::Plain;
+ pub use ansi_term::Colour::*;
+
+ pub fn newser(uid: uid_t, name: &str, group: gid_t) -> User {
+ User {
+ uid: uid,
+ name: name.to_string(),
+ primary_group: group,
+ home_dir: String::new(),
+ shell: String::new(),
+ }
+ }
+
+ // These tests create a new, default Table object, then fill in the
+ // expected style in a certain way. This means we can check that the
+ // right style is being used, as otherwise, it would just be `Plain`.
+ //
+ // Doing things with fields is way easier than having to fake the entire
+ // Metadata struct, which is what I was doing before!
+
+ mod users {
+ use super::*;
+
+ #[test]
+ fn named() {
+ let mut table = Table::default();
+ table.colours.users.user_you = Red.bold();
+
+ let mut users = MockUsers::with_current_uid(1000);
+ users.add_user(newser(1000, "enoch", 100));
+ table.users = users;
+
+ let user = f::User(1000);
+ let expected = Cell::paint(Red.bold(), "enoch");
+ assert_eq!(expected, table.render_user(user))
+ }
+
+ #[test]
+ fn unnamed() {
+ let mut table = Table::default();
+ table.colours.users.user_you = Cyan.bold();
+
+ let users = MockUsers::with_current_uid(1000);
+ table.users = users;
+
+ let user = f::User(1000);
+ let expected = Cell::paint(Cyan.bold(), "1000");
+ assert_eq!(expected, table.render_user(user));
+ }
+
+ #[test]
+ fn different_named() {
+ let mut table = Table::default();
+ table.colours.users.user_someone_else = Green.bold();
+ table.users.add_user(newser(1000, "enoch", 100));
+
+ let user = f::User(1000);
+ let expected = Cell::paint(Green.bold(), "enoch");
+ assert_eq!(expected, table.render_user(user));
+ }
+
+ #[test]
+ fn different_unnamed() {
+ let mut table = Table::default();
+ table.colours.users.user_someone_else = Red.normal();
+
+ let user = f::User(1000);
+ let expected = Cell::paint(Red.normal(), "1000");
+ assert_eq!(expected, table.render_user(user));
+ }
+
+ #[test]
+ fn overflow() {
+ let mut table = Table::default();
+ table.colours.users.user_someone_else = Blue.underline();
+
+ let user = f::User(2_147_483_648);
+ let expected = Cell::paint(Blue.underline(), "2147483648");
+ assert_eq!(expected, table.render_user(user));
+ }
+ }
+
+ mod groups {
+ use super::*;
+
+ #[test]
+ fn named() {
+ let mut table = Table::default();
+ table.colours.users.group_not_yours = Fixed(101).normal();
+
+ let mut users = MockUsers::with_current_uid(1000);
+ users.add_group(Group { gid: 100, name: "folk".to_string(), members: vec![] });
+ table.users = users;
+
+ let group = f::Group(100);
+ let expected = Cell::paint(Fixed(101).normal(), "folk");
+ assert_eq!(expected, table.render_group(group))
+ }
+
+ #[test]
+ fn unnamed() {
+ let mut table = Table::default();
+ table.colours.users.group_not_yours = Fixed(87).normal();
+
+ let users = MockUsers::with_current_uid(1000);
+ table.users = users;
+
+ let group = f::Group(100);
+ let expected = Cell::paint(Fixed(87).normal(), "100");
+ assert_eq!(expected, table.render_group(group));
+ }
+
+ #[test]
+ fn primary() {
+ let mut table = Table::default();
+ table.colours.users.group_yours = Fixed(64).normal();
+
+ let mut users = MockUsers::with_current_uid(2);
+ users.add_user(newser(2, "eve", 100));
+ users.add_group(Group { gid: 100, name: "folk".to_string(), members: vec![] });
+ table.users = users;
+
+ let group = f::Group(100);
+ let expected = Cell::paint(Fixed(64).normal(), "folk");
+ assert_eq!(expected, table.render_group(group))
+ }
+
+ #[test]
+ fn secondary() {
+ let mut table = Table::default();
+ table.colours.users.group_yours = Fixed(31).normal();
+
+ let mut users = MockUsers::with_current_uid(2);
+ users.add_user(newser(2, "eve", 666));
+ users.add_group(Group { gid: 100, name: "folk".to_string(), members: vec![ "eve".to_string() ] });
+ table.users = users;
+
+ let group = f::Group(100);
+ let expected = Cell::paint(Fixed(31).normal(), "folk");
+ assert_eq!(expected, table.render_group(group))
+ }
+
+ #[test]
+ fn overflow() {
+ let mut table = Table::default();
+ table.colours.users.group_not_yours = Blue.underline();
+
+ let group = f::Group(2_147_483_648);
+ let expected = Cell::paint(Blue.underline(), "2147483648");
+ assert_eq!(expected, table.render_group(group));
+ }
+ }
+}