extern crate dono; extern crate os_type; extern crate rustc_serialize; use std::env; use std::io::prelude::*; use std::fs; use std::fs::File; use std::path::PathBuf; use self::rustc_serialize::json; use dono::*; #[test] fn debug_message() { let title = "Test"; let expected = format!("Label '{}'", title); let label = labels::Label::new(&title.to_string()); let message = format!("{:?}", label); assert_eq!(expected, message); } #[test] fn label_new_builds_a_new_label_with_a_title() { let title = "Test"; let label = labels::Label::new(&title.to_string()); assert_eq!(title, label.title); assert_eq!(title, label.previous_title); assert_eq!(false, label.persisted); } #[test] fn label_new_builds_a_new_saved_label_with_a_title() { let title = "Test"; let label = labels::Label::new_saved(&title.to_string()); assert_eq!(title, label.title); assert_eq!(title, label.previous_title); assert_eq!(true, label.persisted); } #[test] fn changed_returns_true_if_the_title_has_changed() { let mut label = labels::Label::new(&"Title".to_string()); assert!(!label.changed()); label.title = "New Title".to_string(); assert!(label.changed()); } #[test] fn can_be_json_encoded_and_decoded() { let title = "Test"; let label = labels::Label::new(&title.to_string()); let encoded = json::encode(&label).unwrap(); let expected = "{\"title\":\"Test\",\"previous_title\":\"Test\",\"persisted\":false}"; assert_eq!(expected, encoded); let decoded: labels::Label = json::decode(&encoded).unwrap(); assert_eq!(label, decoded); } #[test] fn file_system_dependant_tests() { // These tests need to be run sequentially so that one does not temper with // the other save_creates_a_new_file(); save_updates_an_entry_in_the_store(); save_creates_an_entry_in_the_store(); save_ignores_duplicates(); destroy_creates_an_empty_store_if_the_store_doesnt_exist(); destroy_removes_the_label_from_the_store(); destroing_the_last_label_leaves_the_list_empty(); all_returns_a_list_of_all_labels_in_the_store(); } fn save_creates_a_new_file() { move_existing_store(); let store_location = store_location(); let title = "Test"; let mut label = labels::Label::new(&title.to_string()); assert!(!store_location.exists()); label.save().unwrap(); assert!(store_location.exists()); return_existing_store(); } fn save_updates_an_entry_in_the_store() { create_store_with_titles(vec!["github", "twitter", "facebook"]); let new_title = "gitter"; let mut labels = dono::labels::all().unwrap(); let mut label = labels.last_mut().unwrap(); assert_eq!("facebook", label.title); label.title = new_title.to_string(); label.save().unwrap(); let mut labels = dono::labels::all().unwrap(); let label = labels.last_mut().unwrap(); assert_eq!(new_title, label.title); return_existing_store(); } fn save_creates_an_entry_in_the_store() { create_store_with_titles(vec!["github", "twitter", "facebook"]); let title = "gitter"; let mut label = labels::Label::new(&title.to_string()); label.save().unwrap(); let mut labels = dono::labels::all().unwrap(); let label = labels.last_mut().unwrap(); assert_eq!(title, label.title); return_existing_store(); } fn save_ignores_duplicates() { create_store_with_titles(vec!["github", "twitter", "facebook"]); let title = "github"; let mut label = labels::Label::new(&title.to_string()); label.save().unwrap(); let labels = dono::labels::all().unwrap(); assert_eq!(3, labels.len()); return_existing_store(); } fn destroy_creates_an_empty_store_if_the_store_doesnt_exist() { move_existing_store(); let title = "github"; let store_location = store_location(); let label = labels::Label::new(&title.to_string()); assert!(!store_location.exists()); label.destroy().unwrap(); assert!(store_location.exists()); let labels = dono::labels::all().unwrap(); assert_eq!(0, labels.len()); return_existing_store(); } fn destroy_removes_the_label_from_the_store() { create_store_with_titles(vec!["github", "twitter", "facebook"]); let mut labels = dono::labels::all().unwrap(); let len = labels.len(); let label = labels.last_mut().unwrap(); assert_eq!(3, len); assert_eq!("facebook", label.title); label.destroy().unwrap(); let mut labels = dono::labels::all().unwrap(); let len = labels.len(); let label = labels.last_mut().unwrap(); assert_eq!(2, len); assert_eq!("twitter", label.title); return_existing_store(); } fn destroing_the_last_label_leaves_the_list_empty() { move_existing_store(); let title = "github"; let mut label = labels::Label::new(&title.to_string()); label.save().unwrap(); let labels = dono::labels::all().unwrap(); assert_eq!(1, labels.len()); label.destroy().unwrap(); let labels = dono::labels::all().unwrap(); assert_eq!(0, labels.len()); return_existing_store(); } fn all_returns_a_list_of_all_labels_in_the_store() { create_store_with_titles(vec!["github", "twitter", "facebook"]); let labels = dono::labels::all().unwrap(); let expected = vec![ dono::labels::Label::new_saved(&"github".to_string()), dono::labels::Label::new_saved(&"twitter".to_string()), dono::labels::Label::new_saved(&"facebook".to_string()) ]; assert_eq!(expected, labels); return_existing_store(); } // Helper methods fn move_existing_store() { let old_path = store_location(); let new_path = original_store_location(); move_file(old_path, new_path); } fn return_existing_store() { let old_path = store_location(); let new_path = original_store_location(); move_file(new_path, old_path); } fn move_file(old_location: PathBuf, new_location: PathBuf) { if !old_location.exists() { return; } fs::rename(old_location, new_location).unwrap(); } fn create_store_with_titles(titles: Vec<&str>) { move_existing_store(); let store_location = store_location(); let mut file = File::create(store_location).unwrap(); let contents = titles.join("\n"); file.write_all(contents.as_bytes()).unwrap(); } fn store_location() -> PathBuf { let mut home_directory = env::home_dir().unwrap(); // The macOS app stores labels in the Documents folder so we need to // compensate for that fact if os_type::current_platform() == os_type::OSType::OSX { home_directory.push("Documents"); } home_directory.push(".labels"); home_directory } fn original_store_location() -> PathBuf { let mut location = store_location(); location.pop(); location.push(".labels.original"); location }