-
Notifications
You must be signed in to change notification settings - Fork 544
tournament: Put inputs/expectations inline, not in files #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,5 @@ | ||
use std::cmp::Ordering::Equal; | ||
use std::collections::HashMap; | ||
use std::fs::File; | ||
use std::io::{BufRead, BufReader, Write, Result}; | ||
use std::path::Path; | ||
|
||
enum GameResult { | ||
Win, | ||
|
@@ -29,12 +26,9 @@ impl TeamResult { | |
} | ||
} | ||
|
||
pub fn tally(input_filename: &Path, output_filename: &Path) -> Result<u32> { | ||
let reader = BufReader::with_capacity(2048, File::open(input_filename).unwrap()); | ||
let mut count = 0; | ||
pub fn tally(input: &str) -> String { | ||
let mut results: HashMap<String, TeamResult> = HashMap::new(); | ||
for line in reader.lines() { | ||
let line = line.unwrap(); | ||
for line in input.to_string().lines() { | ||
let parts: Vec<&str> = line.trim_right().split(';').collect(); | ||
if parts.len() != 3 { continue; } | ||
let team1 = parts[0]; | ||
|
@@ -44,26 +38,22 @@ pub fn tally(input_filename: &Path, output_filename: &Path) -> Result<u32> { | |
"win" => { | ||
add_game_result(&mut results, team1.to_string(), GameResult::Win); | ||
add_game_result(&mut results, team2.to_string(), GameResult::Loss); | ||
count += 1; | ||
}, | ||
"draw" => { | ||
add_game_result(&mut results, team1.to_string(), GameResult::Draw); | ||
add_game_result(&mut results, team2.to_string(), GameResult::Draw); | ||
count += 1; | ||
}, | ||
"loss" => { | ||
add_game_result(&mut results, team1.to_string(), GameResult::Loss); | ||
add_game_result(&mut results, team2.to_string(), GameResult::Win); | ||
count += 1; | ||
}, | ||
_ => () // Ignore bad lines | ||
} | ||
} | ||
try!(write_tally(&results, output_filename)); | ||
Ok(count) | ||
write_tally(&results) | ||
} | ||
|
||
fn write_tally(results: &HashMap<String, TeamResult>, output_filename: &Path) -> Result<()> { | ||
fn write_tally(results: &HashMap<String, TeamResult>) -> String { | ||
let mut v: Vec<_> = results.iter().map(|(team, r)| { | ||
let games = r.wins + r.draws + r.losses; | ||
let points = r.wins * 3 + r.draws; | ||
|
@@ -75,13 +65,12 @@ fn write_tally(results: &HashMap<String, TeamResult>, output_filename: &Path) -> | |
Equal => a.1.cmp(&(b.1)).reverse(), | ||
other => other | ||
}); | ||
let mut f = try!(File::create(output_filename)); | ||
try!(writeln!(&mut f, "{:30} | MP | W | D | L | P", "Team")); | ||
for &(ref team, games, r, points) in v.iter() { | ||
try!(writeln!(&mut f, "{:30} | {:2} | {:2} | {:2} | {:2} | {:2}", | ||
team, games, r.wins, r.draws, r.losses, points)); | ||
} | ||
Ok(()) | ||
let header = format!("{:30} | MP | W | D | L | P\n", "Team"); | ||
let lines: Vec<_> = v.iter().map(|&(ref team, games, r, points)| { | ||
format!("{:30} | {:2} | {:2} | {:2} | {:2} | {:2}", | ||
team, games, r.wins, r.draws, r.losses, points) | ||
}).collect(); | ||
header + &lines.join("\n") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note that for an empty input, this prints the header and nothing after. No test tests this behavior, so I have nothing to say about whether this appropriate. |
||
} | ||
|
||
fn add_game_result(results: &mut HashMap<String, TeamResult>, team: String, result: GameResult) { | ||
|
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,57 @@ | ||
use std::fs::File; | ||
use std::path::Path; | ||
use std::io::Read; | ||
|
||
extern crate tournament; | ||
|
||
fn file_equal(output_file: &str, expected_file: &str) { | ||
let output = match File::open(&Path::new(output_file)) { | ||
Err(e) => panic!("Couldn't open {}: {}", output_file, e), | ||
Ok(mut f) => { | ||
let mut buf = String::new(); | ||
match f.read_to_string(&mut buf) { | ||
Err(e) => panic!("Couldn't read {}: {}", output_file, e), | ||
Ok(_) => buf | ||
} | ||
} | ||
}; | ||
let expected = match File::open(&Path::new(expected_file)) { | ||
Err(e) => panic!("Couldn't open {}: {}", expected_file, e), | ||
Ok(mut f) => { | ||
let mut buf = String::new(); | ||
match f.read_to_string(&mut buf) { | ||
Err(e) => panic!("Couldn't read {}: {}", expected_file, e), | ||
Ok(_) => buf | ||
} | ||
} | ||
}; | ||
assert_eq!("\n".to_string() + output.as_ref(), "\n".to_string() + expected.as_ref()); | ||
|
||
} | ||
|
||
|
||
#[test] | ||
fn test_good() { | ||
assert_eq!(tournament::tally(&Path::new("tests/input1.txt"), &Path::new("tests/output1.txt")).unwrap(), 6); | ||
file_equal("tests/output1.txt", "tests/expected1.txt"); | ||
let input = "Allegoric Alaskians;Blithering Badgers;win\n".to_string() + | ||
"Devastating Donkeys;Courageous Californians;draw\n" + | ||
"Devastating Donkeys;Allegoric Alaskians;win\n" + | ||
"Courageous Californians;Blithering Badgers;loss\n" + | ||
"Blithering Badgers;Devastating Donkeys;loss\n" + | ||
"Allegoric Alaskians;Courageous Californians;win"; | ||
let expected = "Team | MP | W | D | L | P\n".to_string() + | ||
"Devastating Donkeys | 3 | 2 | 1 | 0 | 7\n" + | ||
"Allegoric Alaskians | 3 | 2 | 0 | 1 | 6\n" + | ||
"Blithering Badgers | 3 | 1 | 0 | 2 | 3\n" + | ||
"Courageous Californians | 3 | 0 | 1 | 2 | 1"; | ||
|
||
assert_eq!(tournament::tally(&input), expected); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_ignore_bad_lines() { | ||
assert_eq!(tournament::tally(&Path::new("tests/input2.txt"), &Path::new("tests/output2.txt")).unwrap(), 6); | ||
file_equal("tests/output2.txt", "tests/expected2.txt"); | ||
let input = "Allegoric Alaskians;Blithering Badgers;win\n".to_string() + | ||
"Devastating Donkeys_Courageous Californians;draw\n" + | ||
"Devastating Donkeys;Allegoric Alaskians;win\n" + | ||
"\n" + | ||
"Courageous Californians;Blithering Badgers;loss\n" + | ||
"Bla;Bla;Bla\n" + | ||
"Blithering Badgers;Devastating Donkeys;loss\n" + | ||
"# Yackity yackity yack\n" + | ||
"Allegoric Alaskians;Courageous Californians;win\n" + | ||
"Devastating Donkeys;Courageous Californians;draw\n" + | ||
"Devastating Donkeys@Courageous Californians;draw"; | ||
let expected = "Team | MP | W | D | L | P\n".to_string() + | ||
"Devastating Donkeys | 3 | 2 | 1 | 0 | 7\n" + | ||
"Allegoric Alaskians | 3 | 2 | 0 | 1 | 6\n" + | ||
"Blithering Badgers | 3 | 1 | 0 | 2 | 3\n" + | ||
"Courageous Californians | 3 | 0 | 1 | 2 | 1"; | ||
|
||
assert_eq!(tournament::tally(&input), expected); | ||
} | ||
|
||
#[test] | ||
#[ignore] | ||
fn test_incomplete_competition() { | ||
assert_eq!(tournament::tally(&Path::new("tests/input3.txt"), &Path::new("tests/output3.txt")).unwrap(), 4); | ||
file_equal("tests/output3.txt", "tests/expected3.txt"); | ||
let input = "Allegoric Alaskians;Blithering Badgers;win\n".to_string() + | ||
"Devastating Donkeys;Allegoric Alaskians;win\n" + | ||
"Courageous Californians;Blithering Badgers;loss\n" + | ||
"Allegoric Alaskians;Courageous Californians;win"; | ||
let expected = "Team | MP | W | D | L | P\n".to_string() + | ||
"Allegoric Alaskians | 3 | 2 | 0 | 1 | 6\n" + | ||
"Blithering Badgers | 2 | 1 | 0 | 1 | 3\n" + | ||
"Devastating Donkeys | 1 | 1 | 0 | 0 | 3\n" + | ||
"Courageous Californians | 2 | 0 | 0 | 2 | 0"; | ||
|
||
assert_eq!(tournament::tally(&input), expected); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like a reminder on the idiomatic-ness of
str
andString
. I will see if I can find an answer myself.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
http://hermanradtke.com/2015/05/03/string-vs-str-in-rust-functions.html argues for using
&str
as argument. I will keep that.On the other hand
String
makes the most sense for what I output since I'm concatenating inwrite_tally