mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
refactor to a library, add integration tests
This commit is contained in:
parent
9f310c76bd
commit
d0744d5178
8 changed files with 56 additions and 59 deletions
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -65,15 +65,6 @@ name = "num-traits"
|
|||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rask"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.40"
|
||||
|
@ -84,6 +75,15 @@ name = "rustc-demangle"
|
|||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "taskwarrior"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.40"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "rask"
|
||||
name = "taskwarrior"
|
||||
version = "0.1.0"
|
||||
authors = ["Dustin J. Mitchell <dustin@mozilla.com>"]
|
||||
|
||||
|
|
18
src/lib.rs
Normal file
18
src/lib.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
#![recursion_limit = "1024"]
|
||||
|
||||
extern crate chrono;
|
||||
extern crate uuid;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod tdb2;
|
||||
mod task;
|
||||
mod errors;
|
||||
|
||||
use std::io::BufRead;
|
||||
pub use task::*;
|
||||
pub use errors::*;
|
||||
|
||||
pub fn parse(filename: &str, reader: impl BufRead) -> Result<Vec<Task>> {
|
||||
Ok(tdb2::parse(filename, reader)?)
|
||||
}
|
47
src/main.rs
47
src/main.rs
|
@ -1,47 +0,0 @@
|
|||
#![recursion_limit = "1024"]
|
||||
|
||||
extern crate chrono;
|
||||
extern crate uuid;
|
||||
#[macro_use]
|
||||
extern crate error_chain;
|
||||
|
||||
mod tdb2;
|
||||
mod task;
|
||||
mod errors;
|
||||
|
||||
use tdb2::parse;
|
||||
use std::io::stdin;
|
||||
|
||||
use errors::*;
|
||||
|
||||
fn main() {
|
||||
if let Err(ref e) = run() {
|
||||
use std::io::Write;
|
||||
let stderr = &mut ::std::io::stderr();
|
||||
let errmsg = "Error writing to stderr";
|
||||
|
||||
writeln!(stderr, "error: {}", e).expect(errmsg);
|
||||
|
||||
for e in e.iter().skip(1) {
|
||||
writeln!(stderr, "caused by: {}", e).expect(errmsg);
|
||||
}
|
||||
|
||||
// The backtrace is not always generated. Try to run this example
|
||||
// with `RUST_BACKTRACE=1`.
|
||||
if let Some(backtrace) = e.backtrace() {
|
||||
writeln!(stderr, "backtrace: {:?}", backtrace).expect(errmsg);
|
||||
}
|
||||
|
||||
::std::process::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
fn run() -> Result<()> {
|
||||
let input = stdin();
|
||||
parse("<stdin>".to_string(), input.lock())?
|
||||
.iter()
|
||||
.for_each(|t| {
|
||||
println!("{:?}", t);
|
||||
});
|
||||
Ok(())
|
||||
}
|
|
@ -97,6 +97,7 @@ impl TaskBuilder {
|
|||
const ANNOTATION_PREFIX: &str = "annotation_";
|
||||
if name.starts_with(ANNOTATION_PREFIX) {
|
||||
let entry = parse_timestamp(&name[ANNOTATION_PREFIX.len()..]).unwrap();
|
||||
// TODO: sort by entry time
|
||||
self.annotations.push(Annotation {
|
||||
entry,
|
||||
description: value.to_string(),
|
||||
|
|
|
@ -10,11 +10,11 @@ use task::Task;
|
|||
use self::ff4::parse_ff4;
|
||||
use self::errors::*;
|
||||
|
||||
pub(super) fn parse(filename: String, reader: impl BufRead) -> Result<Vec<Task>> {
|
||||
pub(crate) fn parse(filename: &str, reader: impl BufRead) -> Result<Vec<Task>> {
|
||||
let mut tasks = vec![];
|
||||
for (i, line) in reader.lines().enumerate() {
|
||||
tasks.push(parse_ff4(&line?).chain_err(|| {
|
||||
ErrorKind::ParseError(filename.clone(), i as u64 + 1)
|
||||
ErrorKind::ParseError(filename.to_string(), i as u64 + 1)
|
||||
})?);
|
||||
}
|
||||
Ok(tasks)
|
||||
|
|
2
tests/data/tdb2-test.data
Normal file
2
tests/data/tdb2-test.data
Normal file
|
@ -0,0 +1,2 @@
|
|||
[description:"https:\/\/phabricator.services.example.com\/D7364 &open;taskgraph&close; Download debian packages" end:"1541705209" entry:"1538520624" modified:"1541705209" phabricatorid:"D7364" priority:"M" project:"moz" status:"completed" tags:"phabricator,respond" uuid:"ca33f6d6-1688-4503-90be-3b3526a32b5a" wait:"1570118809"]
|
||||
[annotation_1541461824:"https:\/\/github.com\/taskcluster\/taskcluster-worker-manager\/pull\/3" description:"https:\/\/github.com\/taskcluster\/taskcluster-worker-manager\/pull\/3 More changes" end:"1541702602" entry:"1541451283" githubbody:"some notes:\n\n1. This is a huge PR, so I'm not expecting a quick turn around at all. If you have questions, let me know and I can hope on Vidyo.\n1. Data persistence is written in a semi-janky way. My intention is to use the time while this is under review to make progress on postgres stuff so that the next review cycle will be using new Postgres things. Which means.... There's a lot of bugs in the concurrency because there's no synchronisation at all in this janky-ish model.\n1. The API is the minimum api required to get provisioning-ish things working\n1. I intend to write a system for automatically testing provider and bidding strategy implementations, so that you can do instantiate a provider\/strategy, stub\/spy it as needed then run a test suite against it and have it do its thing. The idea is that each provider will need to mock their underlying api system in their own way, but the set of tests we run for Provider API conformance would be pretty standardized. This should make writing tests for new providers a lot easier.\n1. The provider\/strategy loading system is intentionally simple. The idea is that these aren't general purpose plugins, but rather special ones. The idea is that the config files would essentially declare instances and then provide constructor arguments to initialize them all... This would make enabling\/disabling providers\/strategies fairly trivial\n1. I decided to drop fake implementations of providers and strategies for testing the provisioning logic and instead opt for Sinon stubs, which I think give us a better testing story\n1. I still intend to have fake providers and bidding strategies for doing API testing.\n\nLet me know, and again, I don't expect or need a quick turn around on this PR.\n" githubcreatedon:"1541451283" githubnamespace:"djmitche" githubnumber:"3.000000" githubrepo:"taskcluster\/taskcluster-worker-manager" githubtitle:"More changes" githubtype:"pull_request" githubupdatedat:"1541699191" githuburl:"https:\/\/github.com\/taskcluster\/taskcluster-worker-manager\/pull\/3" githubuser:"jhford" modified:"1541702602" priority:"H" project:"moz" status:"completed" tags:"respond" uuid:"2186f981-d1f5-4642-b833-5b16b3a2d334"]
|
23
tests/parse.rs
Normal file
23
tests/parse.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
extern crate taskwarrior;
|
||||
extern crate chrono;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
use chrono::prelude::*;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let filename = "tests/data/tdb2-test.data";
|
||||
let file = File::open(filename).unwrap();
|
||||
let tasks = taskwarrior::parse(filename, BufReader::new(file)).unwrap();
|
||||
assert_eq!(
|
||||
tasks[0].description,
|
||||
"https://phabricator.services.example.com/D7364 [taskgraph] Download debian packages"
|
||||
);
|
||||
assert_eq!(tasks[0].entry, Utc.timestamp(1538520624, 0));
|
||||
assert_eq!(tasks[0].udas.get("phabricatorid").unwrap(), "D7364");
|
||||
assert_eq!(tasks[1].annotations[0].entry, Utc.timestamp(1541461824, 0));
|
||||
assert!(tasks[1].annotations[0].description.starts_with(
|
||||
"https://github.com",
|
||||
));
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue