Change layout panics to errors

* Adjust and add tests for the change
This commit is contained in:
a-kenji 2021-08-02 12:03:42 +02:00
parent 9a5b6690af
commit 2e17756785
10 changed files with 354 additions and 84 deletions

View file

@ -16,6 +16,7 @@ parts:
- direction: Vertical - direction: Vertical
split_size: split_size:
Percent: 50 Percent: 50
- direction: Vertical
- direction: Vertical - direction: Vertical
parts: parts:
- direction: Vertical - direction: Vertical

View file

@ -45,6 +45,9 @@ pub enum ConfigError {
IoPath(io::Error, PathBuf), IoPath(io::Error, PathBuf),
// Internal Deserialization Error // Internal Deserialization Error
FromUtf8(std::string::FromUtf8Error), FromUtf8(std::string::FromUtf8Error),
// Missing the tab section in the layout.
Layout(LayoutMissingTabSectionError),
LayoutPartAndTab(LayoutPartAndTabError),
} }
impl Default for Config { impl Default for Config {
@ -129,6 +132,75 @@ impl Config {
} }
} }
// TODO: Split errors up into separate modules
#[derive(Debug, Clone)]
pub struct LayoutMissingTabSectionError;
#[derive(Debug, Clone)]
pub struct LayoutPartAndTabError;
impl fmt::Display for LayoutMissingTabSectionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"MissingTabSectionError:
There needs to be exactly one `tabs` section specified in the layout file, for example:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
- direction: Vertical
- direction: Vertical
"
)
}
}
impl std::error::Error for LayoutMissingTabSectionError {
fn description(&self) -> &str {
"One tab must be specified per Layout."
}
}
impl fmt::Display for LayoutPartAndTabError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"LayoutPartAndTabError:
The `tabs` and `parts` section should not be specified on the same level in the layout file, for example:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
- direction: Vertical
- direction: Vertical
should rather be specified as:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
- direction: Vertical
- direction: Vertical
"
)
}
}
impl std::error::Error for LayoutPartAndTabError {
fn description(&self) -> &str {
"The `tabs` and parts section should not be specified on the same level."
}
}
impl Display for ConfigError { impl Display for ConfigError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self { match self {
@ -138,6 +210,12 @@ impl Display for ConfigError {
} }
ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err), ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err),
ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err), ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err),
ConfigError::Layout(ref err) => {
write!(formatter, "There was an error in the layout file, {}", err)
}
ConfigError::LayoutPartAndTab(ref err) => {
write!(formatter, "There was an error in the layout file, {}", err)
}
} }
} }
} }
@ -149,6 +227,8 @@ impl std::error::Error for ConfigError {
ConfigError::IoPath(ref err, _) => Some(err), ConfigError::IoPath(ref err, _) => Some(err),
ConfigError::Serde(ref err) => Some(err), ConfigError::Serde(ref err) => Some(err),
ConfigError::FromUtf8(ref err) => Some(err), ConfigError::FromUtf8(ref err) => Some(err),
ConfigError::Layout(ref err) => Some(err),
ConfigError::LayoutPartAndTab(ref err) => Some(err),
} }
} }
} }
@ -171,6 +251,18 @@ impl From<std::string::FromUtf8Error> for ConfigError {
} }
} }
impl From<LayoutMissingTabSectionError> for ConfigError {
fn from(err: LayoutMissingTabSectionError) -> ConfigError {
ConfigError::Layout(err)
}
}
impl From<LayoutPartAndTabError> for ConfigError {
fn from(err: LayoutPartAndTabError) -> ConfigError {
ConfigError::LayoutPartAndTab(err)
}
}
// The unit test location. // The unit test location.
#[cfg(test)] #[cfg(test)]
mod config_test { mod config_test {

View file

@ -20,6 +20,8 @@ use std::path::{Path, PathBuf};
use std::vec::Vec; use std::vec::Vec;
use std::{fs::File, io::prelude::*}; use std::{fs::File, io::prelude::*};
use super::config::{LayoutMissingTabSectionError, LayoutPartAndTabError};
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")] #[serde(crate = "self::serde")]
pub enum Direction { pub enum Direction {
@ -43,7 +45,7 @@ pub enum Run {
Command(RunCommand), Command(RunCommand),
} }
// The layout struct that is ultimately used to build the layouts // The layout struct ultimately used to build the layouts.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")] #[serde(crate = "self::serde")]
pub struct Layout { pub struct Layout {
@ -56,6 +58,7 @@ pub struct Layout {
pub run: Option<Run>, pub run: Option<Run>,
} }
// The tab-layout struct used to specify each individual tab.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")] #[serde(crate = "self::serde")]
pub struct TabLayout { pub struct TabLayout {
@ -66,8 +69,8 @@ pub struct TabLayout {
pub run: Option<Run>, pub run: Option<Run>,
} }
// Main layout struct, that carries information based on // Main layout struct, that carries information based on position of tabs
// position of tabs // in relation to the whole layout.
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")] #[serde(crate = "self::serde")]
pub struct MainLayout { pub struct MainLayout {
@ -205,7 +208,9 @@ impl Layout {
// Split the layout into parts that can be reassebled per tab // Split the layout into parts that can be reassebled per tab
// returns the layout pre tab, the parts post tab and the tab layouts // returns the layout pre tab, the parts post tab and the tab layouts
pub fn split_main_and_tab_layout(&self) -> (Layout, Vec<Layout>, Vec<TabLayout>) { pub fn split_main_and_tab_layout(
&self,
) -> Result<(Layout, Vec<Layout>, Vec<TabLayout>), LayoutPartAndTabError> {
let mut main_layout = self.clone(); let mut main_layout = self.clone();
let mut pre_tab_layout = self.clone(); let mut pre_tab_layout = self.clone();
let mut post_tab_layout = vec![]; let mut post_tab_layout = vec![];
@ -220,23 +225,21 @@ impl Layout {
post_tab = true; post_tab = true;
} }
if !main_layout.tabs.is_empty() && !main_layout.parts.is_empty() {
return Err(LayoutPartAndTabError);
}
for part in main_layout.parts.drain(..) { for part in main_layout.parts.drain(..) {
let (curr_pre_layout, mut curr_post_layout, mut curr_tabs) = let (curr_pre_layout, mut curr_post_layout, mut curr_tabs) =
part.split_main_and_tab_layout(); part.split_main_and_tab_layout()?;
// Leaf // Leaf
if !post_tab && part.tabs.is_empty() { if !post_tab && part.tabs.is_empty() {
pre_tab_layout.parts.push(curr_pre_layout); pre_tab_layout.parts.push(curr_pre_layout);
} }
// Todo: Convert into actual Error, or use the future logging system.
if !part.tabs.is_empty() && !part.parts.is_empty() { if !part.tabs.is_empty() && !part.parts.is_empty() {
panic!("Tabs and Parts need to be specified separately."); return Err(LayoutPartAndTabError);
}
// Todo: Convert into actual Error, or use the future logging system.
if (!part.tabs.is_empty() || !curr_tabs.is_empty()) && post_tab {
panic!("Only one tab section should be specified.");
} }
// Node // Node
@ -259,7 +262,7 @@ impl Layout {
} }
} }
} }
(pre_tab_layout, post_tab_layout, tabs) Ok((pre_tab_layout, post_tab_layout, tabs))
} }
pub fn merge_tab_layout(&mut self, tab: TabLayout) { pub fn merge_tab_layout(&mut self, tab: TabLayout) {
@ -271,33 +274,31 @@ impl Layout {
} }
pub fn construct_full_layout(&self, tab_layout: Option<TabLayout>) -> Self { pub fn construct_full_layout(&self, tab_layout: Option<TabLayout>) -> Self {
// The `split_main_and_tab_layout()` error should have returned
// already from deserialisation, so we can assume it is `Ok()`.
let (mut pre_tab_layout, post_tab_layout, _) = self.split_main_and_tab_layout().unwrap();
if let Some(tab_layout) = tab_layout { if let Some(tab_layout) = tab_layout {
let (mut pre_tab_layout, post_tab_layout, _) = self.split_main_and_tab_layout();
pre_tab_layout.merge_tab_layout(tab_layout); pre_tab_layout.merge_tab_layout(tab_layout);
pre_tab_layout.merge_layout_parts(post_tab_layout);
pre_tab_layout
} else { } else {
let (mut pre_tab_layout, post_tab_layout, _) = self.split_main_and_tab_layout();
let default_tab_layout = TabLayout::default(); let default_tab_layout = TabLayout::default();
pre_tab_layout.merge_tab_layout(default_tab_layout); pre_tab_layout.merge_tab_layout(default_tab_layout);
}
pre_tab_layout.merge_layout_parts(post_tab_layout); pre_tab_layout.merge_layout_parts(post_tab_layout);
pre_tab_layout pre_tab_layout
} }
}
pub fn construct_main_layout(&self) -> MainLayout { pub fn construct_main_layout(&self) -> Result<MainLayout, ConfigError> {
let (pre_tab, post_tab, tabs) = self.split_main_and_tab_layout(); let (pre_tab, post_tab, tabs) = self.split_main_and_tab_layout()?;
// Todo: A proper LayoutError
if tabs.is_empty() { if tabs.is_empty() {
panic!("The layout file should have a [`tabs`] section specified"); return Err(ConfigError::Layout(LayoutMissingTabSectionError));
} }
MainLayout { Ok(MainLayout {
pre_tab, pre_tab,
post_tab, post_tab,
tabs, tabs,
} })
} }
fn from_vec_tab_layout(tab_layout: Vec<TabLayout>) -> Vec<Self> { fn from_vec_tab_layout(tab_layout: Vec<TabLayout>) -> Vec<Self> {

View file

@ -0,0 +1,17 @@
---
direction: Horizontal
parts:
- direction: Horizontal
tabs:
- direction: Vertical
parts:
- direction: Horizontal
split_size:
Percent: 50
parts:
- direction: Vertical
split_size:
Percent: 50
- direction: Vertical
split_size:
Percent: 50

View file

@ -1,25 +0,0 @@
---
direction: Horizontal
parts:
- direction: Horizontal
tabs:
- direction: Vertical
parts:
- direction: Horizontal
split_size:
Percent: 50
- direction: Horizontal
parts:
- direction: Vertical
split_size:
Percent: 50
- direction: Vertical
split_size:
Percent: 50
tabs:
- direction: Vertical
split_size:
Percent: 50
- direction: Vertical
split_size:
Percent: 50

View file

@ -0,0 +1,25 @@
---
direction: Vertical
parts:
- direction: Horizontal
tabs:
- direction: Horizontal
split_size:
Percent: 50
- direction: Horizontal
split_size:
Percent: 50
parts:
- direction: Horizontal
split_size:
Percent: 50
- direction: Horizontal
- direction: Vertical
split_size:
Percent: 50
parts:
- direction: Vertical
split_size:
Percent: 50
- direction: Horizontal
- direction: Horizontal

View file

@ -23,7 +23,7 @@ fn default_layout_is_ok() {
fn default_layout_has_one_tab() { fn default_layout_has_one_tab() {
let path = default_layout_dir("default.yaml".into()); let path = default_layout_dir("default.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 1); assert_eq!(main_layout.tabs.len(), 1);
} }
@ -31,7 +31,7 @@ fn default_layout_has_one_tab() {
fn default_layout_has_one_pre_tab() { fn default_layout_has_one_pre_tab() {
let path = default_layout_dir("default.yaml".into()); let path = default_layout_dir("default.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.pre_tab.parts.len(), 1); assert_eq!(main_layout.pre_tab.parts.len(), 1);
} }
@ -39,7 +39,7 @@ fn default_layout_has_one_pre_tab() {
fn default_layout_has_one_post_tab() { fn default_layout_has_one_post_tab() {
let path = default_layout_dir("default.yaml".into()); let path = default_layout_dir("default.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.post_tab.len(), 1); assert_eq!(main_layout.post_tab.len(), 1);
} }
@ -47,7 +47,7 @@ fn default_layout_has_one_post_tab() {
fn default_layout_merged_correctly() { fn default_layout_merged_correctly() {
let path = default_layout_dir("default.yaml".into()); let path = default_layout_dir("default.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone())); let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone()));
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -85,7 +85,7 @@ fn default_layout_merged_correctly() {
fn default_layout_new_tab_correct() { fn default_layout_new_tab_correct() {
let path = default_layout_dir("default.yaml".into()); let path = default_layout_dir("default.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(None); let tab_layout = main_layout.construct_tab_layout(None);
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -137,7 +137,7 @@ fn default_disable_status_layout_is_ok() {
fn default_disable_status_layout_has_one_tab() { fn default_disable_status_layout_has_one_tab() {
let path = default_layout_dir("disable-status-bar.yaml".into()); let path = default_layout_dir("disable-status-bar.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 1); assert_eq!(main_layout.tabs.len(), 1);
} }
@ -145,7 +145,7 @@ fn default_disable_status_layout_has_one_tab() {
fn default_disable_status_layout_has_one_pre_tab() { fn default_disable_status_layout_has_one_pre_tab() {
let path = default_layout_dir("disable-status-bar.yaml".into()); let path = default_layout_dir("disable-status-bar.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.pre_tab.parts.len(), 1); assert_eq!(main_layout.pre_tab.parts.len(), 1);
} }
@ -153,7 +153,7 @@ fn default_disable_status_layout_has_one_pre_tab() {
fn default_disable_status_layout_has_no_post_tab() { fn default_disable_status_layout_has_no_post_tab() {
let path = default_layout_dir("disable-status-bar.yaml".into()); let path = default_layout_dir("disable-status-bar.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
assert!(main_layout.post_tab.is_empty()); assert!(main_layout.post_tab.is_empty());
} }
@ -168,7 +168,7 @@ fn three_panes_with_tab_is_ok() {
fn three_panes_with_tab_has_one_tab() { fn three_panes_with_tab_has_one_tab() {
let path = layout_test_dir("three-panes-with-tab.yaml".into()); let path = layout_test_dir("three-panes-with-tab.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 1); assert_eq!(main_layout.tabs.len(), 1);
} }
@ -176,7 +176,7 @@ fn three_panes_with_tab_has_one_tab() {
fn three_panes_with_tab_no_post_tab() { fn three_panes_with_tab_no_post_tab() {
let path = layout_test_dir("three-panes-with-tab.yaml".into()); let path = layout_test_dir("three-panes-with-tab.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert!(main_layout.post_tab.is_empty()); assert!(main_layout.post_tab.is_empty());
} }
@ -184,7 +184,7 @@ fn three_panes_with_tab_no_post_tab() {
fn three_panes_with_tab_no_pre_tab() { fn three_panes_with_tab_no_pre_tab() {
let path = layout_test_dir("three-panes-with-tab.yaml".into()); let path = layout_test_dir("three-panes-with-tab.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert!(main_layout.pre_tab.parts.is_empty()); assert!(main_layout.pre_tab.parts.is_empty());
} }
@ -192,7 +192,7 @@ fn three_panes_with_tab_no_pre_tab() {
fn three_panes_with_tab_merged_correctly() { fn three_panes_with_tab_merged_correctly() {
let path = layout_test_dir("three-panes-with-tab.yaml".into()); let path = layout_test_dir("three-panes-with-tab.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone())); let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone()));
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -244,7 +244,7 @@ fn three_panes_with_tab_merged_correctly() {
fn three_panes_with_tab_new_tab_is_correct() { fn three_panes_with_tab_new_tab_is_correct() {
let path = layout_test_dir("three-panes-with-tab.yaml".into()); let path = layout_test_dir("three-panes-with-tab.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(None); let tab_layout = main_layout.construct_tab_layout(None);
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -273,7 +273,7 @@ fn three_panes_with_tab_and_default_plugins_is_ok() {
fn three_panes_with_tab_and_default_plugins_has_one_tab() { fn three_panes_with_tab_and_default_plugins_has_one_tab() {
let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into()); let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 1); assert_eq!(main_layout.tabs.len(), 1);
} }
@ -281,7 +281,7 @@ fn three_panes_with_tab_and_default_plugins_has_one_tab() {
fn three_panes_with_tab_and_default_plugins_one_post_tab() { fn three_panes_with_tab_and_default_plugins_one_post_tab() {
let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into()); let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.post_tab.len(), 1); assert_eq!(main_layout.post_tab.len(), 1);
} }
@ -289,7 +289,7 @@ fn three_panes_with_tab_and_default_plugins_one_post_tab() {
fn three_panes_with_tab_and_default_plugins_has_pre_tab() { fn three_panes_with_tab_and_default_plugins_has_pre_tab() {
let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into()); let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert!(!main_layout.pre_tab.parts.is_empty()); assert!(!main_layout.pre_tab.parts.is_empty());
} }
@ -297,7 +297,7 @@ fn three_panes_with_tab_and_default_plugins_has_pre_tab() {
fn three_panes_with_tab_and_default_plugins_merged_correctly() { fn three_panes_with_tab_and_default_plugins_merged_correctly() {
let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into()); let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone())); let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone()));
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -365,7 +365,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() { fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into()); let path = layout_test_dir("three-panes-with-tab-and-default-plugins.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(None); let tab_layout = main_layout.construct_tab_layout(None);
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -410,7 +410,7 @@ fn deeply_nested_tab_is_ok() {
fn deeply_nested_tab_has_one_tab() { fn deeply_nested_tab_has_one_tab() {
let path = layout_test_dir("deeply-nested-tab-layout.yaml".into()); let path = layout_test_dir("deeply-nested-tab-layout.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 1); assert_eq!(main_layout.tabs.len(), 1);
} }
@ -418,7 +418,7 @@ fn deeply_nested_tab_has_one_tab() {
fn deeply_nested_tab_three_post_tab() { fn deeply_nested_tab_three_post_tab() {
let path = layout_test_dir("deeply-nested-tab-layout.yaml".into()); let path = layout_test_dir("deeply-nested-tab-layout.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.post_tab.len(), 3); assert_eq!(main_layout.post_tab.len(), 3);
} }
@ -426,7 +426,7 @@ fn deeply_nested_tab_three_post_tab() {
fn deeply_nested_tab_has_many_pre_tab() { fn deeply_nested_tab_has_many_pre_tab() {
let path = layout_test_dir("deeply-nested-tab-layout.yaml".into()); let path = layout_test_dir("deeply-nested-tab-layout.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert!(!main_layout.pre_tab.parts.is_empty()); assert!(!main_layout.pre_tab.parts.is_empty());
} }
@ -434,7 +434,7 @@ fn deeply_nested_tab_has_many_pre_tab() {
fn deeply_nested_tab_merged_correctly() { fn deeply_nested_tab_merged_correctly() {
let path = layout_test_dir("deeply-nested-tab-layout.yaml".into()); let path = layout_test_dir("deeply-nested-tab-layout.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout(); let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone())); let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone()));
let merged_layout = Layout { let merged_layout = Layout {
direction: Direction::Horizontal, direction: Direction::Horizontal,
@ -519,17 +519,172 @@ fn deeply_nested_tab_merged_correctly() {
} }
#[test] #[test]
#[should_panic] fn no_tabs_specified_should_err() {
// TODO Make error out of this let path = layout_test_dir("no-tabs-should-error.yaml".into());
fn no_tabs_specified_should_panic() {
let path = layout_test_dir("no-tabs-should-panic.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let _main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout();
assert!(main_layout.is_err());
} }
#[test] #[test]
fn multiple_tabs_specified_should_not_panic() { fn tabs_and_parts_specified_together_should_should_err() {
let path = layout_test_dir("multiple-tabs-should-panic.yaml".into()); let path = layout_test_dir("tabs-and-parts-together-should-error.yaml".into());
let layout = Layout::new(&path); let layout = Layout::new(&path);
let _main_layout = layout.unwrap().construct_main_layout(); let main_layout = layout.unwrap().construct_main_layout();
assert!(main_layout.is_err());
}
#[test]
fn multiple_tabs_specified_should_not_err() {
let path = layout_test_dir("multiple-tabs-should-not-error.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout();
assert!(main_layout.is_ok())
}
#[test]
fn three_tabs_is_ok() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
assert!(layout.is_ok());
}
#[test]
fn three_tabs_has_three_tabs() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.tabs.len(), 3);
}
#[test]
fn three_tabs_has_one_post_tab() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.unwrap().construct_main_layout().unwrap();
assert_eq!(main_layout.post_tab.len(), 1);
}
#[test]
fn three_tabs_tab_one_merged_correctly() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[0].clone()));
let merged_layout = Layout {
direction: Direction::Vertical,
parts: vec![
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: Some(SplitSize::Percent(50)),
run: None,
},
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: None,
run: None,
},
],
tabs: vec![],
split_size: None,
run: None,
};
assert_eq!(merged_layout, tab_layout);
}
#[test]
fn three_tabs_tab_two_merged_correctly() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[1].clone()));
let merged_layout = Layout {
direction: Direction::Vertical,
parts: vec![
Layout {
direction: Direction::Horizontal,
parts: vec![
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: Some(SplitSize::Percent(50)),
run: None,
},
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: None,
run: None,
},
],
tabs: vec![],
split_size: Some(SplitSize::Percent(50)),
run: None,
},
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: None,
run: None,
},
],
tabs: vec![],
split_size: None,
run: None,
};
assert_eq!(merged_layout, tab_layout);
}
#[test]
fn three_tabs_tab_three_merged_correctly() {
let path = layout_test_dir("three-tabs-merged-correctly.yaml".into());
let layout = Layout::new(&path);
let main_layout = layout.as_ref().unwrap().construct_main_layout().unwrap();
let tab_layout = main_layout.construct_tab_layout(Some(main_layout.tabs[2].clone()));
let merged_layout = Layout {
direction: Direction::Vertical,
parts: vec![
Layout {
direction: Direction::Vertical,
parts: vec![
Layout {
direction: Direction::Vertical,
parts: vec![],
tabs: vec![],
split_size: Some(SplitSize::Percent(50)),
run: None,
},
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: None,
run: None,
},
],
tabs: vec![],
split_size: Some(SplitSize::Percent(50)),
run: None,
},
Layout {
direction: Direction::Horizontal,
parts: vec![],
tabs: vec![],
split_size: None,
run: None,
},
],
tabs: vec![],
split_size: None,
run: None,
};
assert_eq!(merged_layout, tab_layout);
} }

View file

@ -159,13 +159,10 @@ impl Setup {
_ => false, _ => false,
}; };
log::info!("{:?}", clean);
let config = if !clean { let config = if !clean {
match Config::try_from(opts) { match Config::try_from(opts) {
Ok(config) => config, Ok(config) => config,
Err(e) => { Err(e) => {
eprintln!("There was an error in the config file:");
return Err(e); return Err(e);
} }
} }
@ -188,12 +185,19 @@ impl Setup {
None => None, None => None,
Some(Ok(layout)) => Some(layout), Some(Ok(layout)) => Some(layout),
Some(Err(e)) => { Some(Err(e)) => {
eprintln!("There was an error in the layout file:");
return Err(e); return Err(e);
} }
} }
.map(|layout| layout.construct_main_layout()); .map(|layout| layout.construct_main_layout());
let layout = match layout {
None => None,
Some(Ok(layout)) => Some(layout),
Some(Err(e)) => {
return Err(e);
}
};
if let Some(Command::Setup(ref setup)) = &opts.command { if let Some(Command::Setup(ref setup)) = &opts.command {
setup.from_cli(opts, &config_options).map_or_else( setup.from_cli(opts, &config_options).map_or_else(
|e| { |e| {