Tests that are expected to fail
We could make our tests panic and annotate tests with #[should_panic]
, but as our methods return Result
, the is_err
method tells us that the correct method call failed.
Insertion failure
A double insertion of the same document should fail:
# #![allow(unused_variables)] #fn main() { #[test] fn double_insertion_should_fail() { with("double_insertion.sqlite", |db| { let document = Document { id: String::from("asdf"), revision: 0, hash: vec![0u8], data: String::from(r#"{ "a": 1, "b": 123 }"#), }; document.insert(&db).expect("Unable to insert document."); let second_insert_result = document.insert(&db); assert!(second_insert_result.is_err()); }); } #}
Actually, this test is wrong. In CouchDB a document can have many revisions, making id
, revision
and hash
unique.
Insertion failure only when same revision
This fails as expected:
# #![allow(unused_variables)] #fn main() { #[test] fn insert_multiple_revisions() { with("insert_multiple_revisions.sqlite", |db| { let insert = |revision: i64| { let document = Document { id: String::from("asdf"), revision: revision, hash: vec![0u8], data: String::from(r#"{ "a": 1, "b": 123 }"#), }; document.insert(&db).expect("Unable to insert document."); }; insert(0); insert(1); }); } #}
We'll fix it by removing primary key
from id
:
# #![allow(unused_variables)] #fn main() { fn create_table(db: &Connection) -> Result<(), SqliteError> { db.execute_batch( "create table documents ( id text not null, revision integer not null, hash blob not null, data text not null )", ) } #}
Running tests again does not seem to have fixed insert_multiple_revisions
, also double_insertion_should_fail
fails now:
running 4 tests
test tests::database::creating_database_twice_should_not_fail ... ok
test tests::database::insert_multiple_revisions ... FAILED
test tests::database::double_insertion_should_fail ... FAILED
test tests::database::insertion ... ok
As the tests paniced, remove_file
in with
never runs. Fix it by removing file before opening:
# #![allow(unused_variables)] #fn main() { fn with<F>(filename: &str, test: F) where F: Fn(Connection) -> (), { remove_file(filename).unwrap_or(()); let db = get_db_create_if_missing(filename); test(db); remove_file(filename).unwrap(); } #}
unwrap_or(())
ignores any errors in deleting the file.
Running tests again:
running 4 tests
test tests::database::creating_database_twice_should_not_fail ... ok
test tests::database::double_insertion_should_fail ... FAILED
test tests::database::insert_multiple_revisions ... ok
test tests::database::insertion ... ok
insert_multiple_revisions
is OK, but double_insertion_should_fail
is still failing. It fails as primary key
constraint was removed.
Adding a unique constraint should fix id:
# #![allow(unused_variables)] #fn main() { fn create_table(db: &Connection) -> Result<(), SqliteError> { db.execute_batch( "create table documents ( id text not null, revision integer not null, hash blob not null, data text not null, unique(id, revision, hash) ); ", ) } #}
Get non-existent document
Getting a missing document should fail:
# #![allow(unused_variables)] #fn main() { #[test] fn get_by_missing_id_should_fail() { with("get_by_id_missing.sqlite", |db| { let result = Document::get_by_id("asdf", &db); assert!(result.is_err()); }); } #}
Make sure all tests pass:
running 5 tests
test tests::database::get_by_missing_id_should_fail ... ok
test tests::database::creating_database_twice_should_not_fail ... ok
test tests::database::double_insertion_should_fail ... ok
test tests::database::insert_multiple_revisions ... ok
test tests::database::insertion ... ok
Next up: Get by id should return all revisions of document.